2010-07-28 10 views

Odpowiedz

4

Nie jestem ekspertem od montażu, ale wielkość słowa (na x86, 32-bitach) czyta/zapisuje powinna już być atomowa.

Powód, dla którego należy zablokować przyrost, jest taki, że jest to zarówno odczyt, jak i zapis.

+0

Myślę, że masz rację. To ma sens. Dzięki. – IamIC

+0

Nie zapomnij przyjąć odpowiedzi, jeśli ci pomogło;) –

+4

Nie zawsze! Jeśli adres pamięci znajduje się w pamięci podręcznej, która korzysta z drugiego procesora w jednostce procesora, odczyt nie ma charakteru atomowego. Tak więc użyj "LOCK CMPXCHG EAX, [var]", który najpierw buforuje pamięć podręczną. –

1

Dla zwykłego czytania, chodzi głównie o wyrównanie. Najprostszym sposobem zapewnienia odczytu atomowego jest zawsze stosowanie "naturalnego" wyrównania - tj. Wyrównanie jest co najmniej tak samo duże jak rozmiar elementu (np. 32-bitowy element jest wyrównany 32-bitowo).

Nieuzasadnione odczyty niekoniecznie są atomowe. W ekstremalnym przykładzie rozważ czytanie 32-bitowej wartości w nieparzystym adresie, gdzie pierwszy bajt znajduje się w jednej linii pamięci podręcznej, a pozostałe trzy bajty znajdują się w innej linii pamięci podręcznej. W takim przypadku odczyt atomowy jest zasadniczo niemożliwy.

Ponieważ (przynajmniej większość) procesorów korzysta z 64-bitowej magistrali pamięci, największym elementem, który może mieć nadzieję na odczyt atomowy, jest 64-bitowy.

5

Jak wyjaśnić w this postu:

dostępy do Cacheable pamięci, które są Podział całej szerokości autobusowych, linii pamięci podręcznej, i strona granice nie są gwarantowane być atomowej przez Intel Core 2 Duo, Procesory Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6, Pentium i Intel486. Procesory Intel Core 2 Duo, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon i P6 zapewniają sygnały sterujące autobusem , które pozwalają podsystemom pamięci zewnętrznej na dzielenie dostępu atomowego; jednak brak dostępu do danych będzie mieć wpływ na wydajność na wydajność procesora i należy go unikać.

więc używać:

LOCK  CMPXCHG EAX, [J] 

LOCK CMPXCHG pamięć cache i pierwszy płot niż porównanie z wartością EAX docelowym, jeśli wartość docelowa nie EQU wtedy wynik w EAX jest wartość docelowego.

EDIT: linki do:

Intel® 64 and IA-32 Architectures Software Developer’s Manuals

W Volume 3A: System Programming Guide sekcja Check 8.1.1

Sprawdź również: Optimization Reference Manual section: CHAPTER 7 OPTIMIZING CACHE USAGE

+0

To nie będzie kompilować, ponieważ [J] jest wskaźnikiem pamięci. Musi to być wartość rejestru. To jest haczyk-22, którego nie mogę ominąć. – IamIC

+1

Widzę z twojego drugiego posta, że ​​to właściwie nie jest problem, o ile wartość jest wyrównana i z wykorzystaniem szerokości magistrali procesora. – IamIC

+0

@IamIC: Nie szerokość autobusu, dokładnie. Najniższym wspólnym mianownikiem dla gwarancji Intela i AMD jest to, że 'mov' load/store jest atomowe [jeśli nie przekracza granicy 8 bajtów (dla buforowanych dostępów).] (Https://stackoverflow.com/a/36685056/224132) Lub dla nieokreślonego, jeśli jest wyrównany lub 16-bitowy dostęp, który nie przekracza granicy dwordu. Również '[J]' jest po prostu bezwzględnym lub (w x86-64) trybem adresowania względnego RIP. To nie jest dwukierunkowe. Zbiera się dobrze. Składnia MASM często pomijała '[]', ale są one opcjonalne w MASM i wymagane w NASM. –

1

To ciekawe, aby przeczytać inne odpowiedzi. Myślę, że @GJ jest prawdopodobnie na pieniądze.

Przez wiele lat zawsze było prawdą, że 32-bitowy odczyt i zapis był atomowy. Dopiero w ostatnich latach z bardzo agresywnym buforowaniem nie jest to już zagwarantowane.

Domyślam się, że dlatego wolę C++, Java lub niektóre takie między mną a kodem maszynowym. W dzisiejszych czasach kod maszynowy jest zbyt skomplikowany, aby można go było niezawodnie zapisać (chyba że robisz to za dużo, aby zachować swoje umiejętności). Na szczęście dzisiejsze kompilatory optymalizacyjne są tak dobre, że rzadko potrzebujesz wydajności zoptymalizowanego ręcznie asemblera.

+0

C++ nie gwarantuje niczego na temat semantyki pamięci ponad to, co robi procesor, ani Java bez niej. –

+0

C++ może zagwarantować dostęp atomowy dla typów atomowych (rzeczy C++ 11), podobnie jak C (C11). –

Powiązane problemy