2010-07-28 13 views
5

So come scrivere un valore atomicamente in ASM x86. Ma come faccio a leggerne uno? Il prefisso LOCK non può essere utilizzato con mov.Come si legge un valore in x86 ASM in modo atomico?

Per aumentare un valore, che sto facendo:

lock inc dword ptr Counter 

Come posso leggere contatore in un modo thread-safe?

risposta

4

Non sono un esperto di assemblaggio, ma le letture/scritture su word-size (su x86, 32-bit) dovrebbero essere già atomiche.

Il motivo per cui è necessario bloccare l'incremento è perché si tratta sia di una lettura che di una scrittura.

+0

Penso che tu abbia ragione. Ciò ha senso. Grazie. – IamIC

+0

Non dimenticare di accettare una risposta se ti ha aiutato;) –

+4

Non sempre! Se l'indirizzo di memoria è nella cache che usa la seconda CPU nella CPU multy, la lettura non è garantita per essere atomica. Quindi usa "LOCK CMPXCHG EAX, [var]" che prima memorizza la memoria cache. –

1

Per una lettura semplice, si tratta principalmente di allineamento. Il modo più semplice per assicurare la lettura atomica è di usare sempre l'allineamento "naturale" - cioè, l'allineamento è tanto grande quanto la dimensione dell'oggetto (ad esempio, l'elemento a 32 bit è allineato a 32 bit).

Le letture disallineate non sono necessariamente atomiche. Per un esempio estremo, considera la lettura di un valore a 32 bit in corrispondenza di un indirizzo dispari in cui il primo byte si trova in una riga della cache e gli altri tre byte in un'altra riga della cache. In tal caso, una lettura atomica è essenzialmente impossibile.

Poiché (almeno la maggior parte) i processori utilizzano un bus di memoria a 64 bit, l'elemento più grande che può essere letto atomicamente è 64 bit.

5

come spiego a voi in this posta:

accessi alla memoria cacheable che sono spaccatura tra larghezze di autobus, linee di cache, e pagina confini non sono garantiti essere atomica da parte del processore Intel Core 2 Duo, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6, Pentium e Processori Intel486. L'Intel Core 2 Duo, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon e P6 familiari processori forniscono segnali di controllo del bus che permettono sottosistemi di memoria esterni per rendere scissione accessi atomico; tuttavia, gli accessi ai dati non allineati saranno impattano seriamente sulle prestazioni del processore e dovrebbero essere evitati.

in modo da utilizzare:

LOCK  CMPXCHG EAX, [J] 

BLOCCO cmpxchg memoria cache di primo recinzione e di confrontare l'EAX con valore di destinazione, se il valore di destinazione non EQU poi il risultato in EAX è valore di destinazione.

EDIT: LINK A:

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

In Volume 3A: System Programming Guide sezione di controllo 8.1.1

controllare anche: Optimization Reference Manual section: CHAPTER 7 OPTIMIZING CACHE USAGE

+0

Questo non verrà compilato poiché [J] è un puntatore di memoria. Deve essere un valore di registro. Questo è il trucco-22 Non posso andare in giro. – IamIC

+1

Vedo dal tuo altro post che questo in realtà non è un problema fintanto che il valore è allineato e con la larghezza del bus della CPU. – IamIC

+0

@IamIC: non la larghezza del bus, esattamente. Il minimo comune denominatore tra le garanzie di Intel e AMD è che il carico/archivio 'mov' è atomico [se non attraversa un limite di 8 byte (per gli accessi memorizzati nella cache).] (Https://stackoverflow.com/a/36685056/224132) O per la cache, se è allineata o un accesso a 16 bit che non attraversa un confine dword. Anche '[J]' è semplicemente un assoluto o (in x86-64) una modalità di indirizzamento relativa al RIP. Non è una doppia deviazione. Si monta bene. La sintassi MASM spesso omettere '[]', ma sono facoltative in MASM e richieste in NASM. –

1

E 'interessante leggere le altre risposte. Penso che @ GJ sia probabilmente in the money.

Per molti anni è sempre stato vero che la lettura e la scrittura a 32 bit erano atomiche. È solo negli ultimi anni con il caching veramente aggressivo che questo non è più garantito.

Immagino che sia per questo che preferisco C++, Java o qualcosa del genere tra me e il codice macchina. In questi giorni il codice macchina è troppo complesso per scrivere in modo affidabile (a meno che non lo fai un lotto per mantenere le tue abilità nitide). Fortunatamente, i compilatori di ottimizzazione di oggi sono così buoni che raramente hai bisogno delle prestazioni di un assemblatore ottimizzato a mano.

+0

Il C++ non garantisce nulla sulla semantica della memoria al di sopra di ciò che fa la CPU, e nemmeno Java senza volatile. –

+0

C++ può garantire accessi atomici per tipi atomici (roba C++ 11), così come C (C11). –

Problemi correlati