2015-08-24 12 views
5

Le operazioni atomiche per i target mobili Delphi sono basate sulla famiglia di funzioni intrinseche AtomicXXX. Il documentation dice:Quali sono i requisiti di allineamento per le funzioni intrinseche atomiche?

Poiché i compilatori mobili Delphi non supportano un built-in assemblatore, l'unità di sistema fornisce quattro funzioni intrinseche atomici che forniscono un modo per atomicamente scambio, valori di scambio, di incremento e memoria decremento confrontare e .

Queste quattro funzioni sono:

Funzioni RTL che forniscono operazioni atomiche, ad esempio i metodi di classe statici della classe TInterlocked sono basati su questi quattro elementi intrinseci.

Per i compilatori mobili che hanno come target ARMv7, esistono requisiti di allineamento per questi quattro elementi intrinseci atomici? Se sì, quali sono?

La documentazione non elenca tali requisiti. Tuttavia, la documentazione è stata notoriamente inaccurata e non sono fiducioso di considerare l'assenza di requisiti dichiarati come prova definitiva del fatto che tali requisiti non esistono.

Per quanto lieve, XE8 documentation for intrinsic functions afferma che questi intrinseci atomici non sono supportati dai compilatori desktop. Non è corretto: questi elementi intrinseci sono supportati dai compilatori desktop.

risposta

4

XE8 compila

var 
    a: integer; 

AtomicIncrement(a); 

a

3e: 2201  movs r2, #1 
40: 900c  str r0, [sp, #48] ; 0x30 
42: 910b  str r1, [sp, #44] ; 0x2c 
44: 920a  str r2, [sp, #40] ; 0x28 
46: 980b  ldr r0, [sp, #44] ; 0x2c 
48: e850 1f00 ldrex r1, [r0] 
4c: 9a0a  ldr r2, [sp, #40] ; 0x28 
4e: 4411  add r1, r2 
50: e840 1300 strex r3, r1, [r0] 
54: 2b00  cmp r3, #0 
56: d1f6  bne.n 46 <_NativeMain+0x46> 

Così l'atomicità è implementato utilizzando il ldrex/strex.

Se sto interpretando correttamente le informazioni su community.arm.com, l'allineamento richiesto è allineato in DWORD per le operazioni a 4 byte (ldrd/strd) e allineato a QWORD per le operazioni a 8 byte.

Altre funzioni atomiche sono implementate in modo simile, quindi dovrebbero essere applicati gli stessi requisiti.

AtomicDecrement(a); 

68: 980f  ldr r0, [sp, #60] ; 0x3c 
6a: e850 1f00 ldrex r1, [r0] 
6e: 9a0e  ldr r2, [sp, #56] ; 0x38 
70: 1a89  subs r1, r1, r2 
72: e840 1300 strex r3, r1, [r0] 
76: 2b00  cmp r3, #0 
78: d1f6  bne.n 68 <_NativeMain+0x68> 

AtomicExchange(a,b); 

82: 990f  ldr r1, [sp, #60] ; 0x3c 
84: 6008  str r0, [r1, #0] 
86: 4873  ldr r0, [pc, #460] ; (254 <_NativeMain+0x254>) 
88: 9a10  ldr r2, [sp, #64] ; 0x40 
8a: 5880  ldr r0, [r0, r2] 
8c: 6800  ldr r0, [r0, #0] 
8e: f3bf 8f5b dmb ish 
92: 900d  str r0, [sp, #52] ; 0x34 
94: 980f  ldr r0, [sp, #60] ; 0x3c 
96: e850 1f00 ldrex r1, [r0] 
9a: 9b0d  ldr r3, [sp, #52] ; 0x34 
9c: e840 3200 strex r2, r3, [r0] 
a0: 2a00  cmp r2, #0 
a2: 910c  str r1, [sp, #48] ; 0x30 
a4: d1f6  bne.n 94 <_NativeMain+0x94> 

AtomicCmpExchange(a, 42, 17); 

ae: 990f  ldr r1, [sp, #60] ; 0x3c 
b0: 6008  str r0, [r1, #0] 
b2: f3bf 8f5b dmb ish 
b6: 202a  movs r0, #42 ; 0x2a 
b8: 2211  movs r2, #17 
ba: 900b  str r0, [sp, #44] ; 0x2c 
bc: 920a  str r2, [sp, #40] ; 0x28 
be: 980f  ldr r0, [sp, #60] ; 0x3c 
c0: e850 1f00 ldrex r1, [r0] 
c4: 9a0a  ldr r2, [sp, #40] ; 0x28 
c6: 4291  cmp r1, r2 
c8: d105  bne.n d6 <_NativeMain+0xd6> 
ca: 990b  ldr r1, [sp, #44] ; 0x2c 
cc: 9a0f  ldr r2, [sp, #60] ; 0x3c 
ce: e842 1000 strex r0, r1, [r2] 
d2: 2800  cmp r0, #0 
d4: d1f3  bne.n be <_NativeMain+0xbe> 
+0

Requisiti di allineamento per LDREX e STREX deriva dall'uso di monitor esclusiva non dai requisiti di allineamento generici per LDR (D)/STR (D) –

3

L'atomicità viene solitamente implementata mediante LDREX e STREX (istruzioni di caricamento esclusivo/archivio esclusivo). Queste istruzioni usano un concetto chiamato monitor esclusivi. Check out: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.html Cercare 'Exclusives Prenotazione granello'

così i vostri requisiti di allineamento è Attuazione specifiche e saranno decisi dal meccanismo del monitor esclusiva implementato sul proprio hardware. Ti suggerisco di dare un'occhiata alla documentazione CPU/SoC per la sezione esclusiva del monitor.

Es. Quando si utilizzano i monitor interni e questi monitor sono solitamente implementati a livello di cache (in genere L2). Ogni linea della cache avrà un monitor.

  • Così i dati atomici devono essere contenuti in una singola linea di cache, allineamento seguirà da questo requisito
  • Se più Atomics occupano la stessa linea di cache, quando uno atomica è in stato esclusiva tutti gli altri Atomics della stessa la linea della cache sarà in uno stato esclusivo falso. Ciò causerà inefficienze nel blocco. Avere gli atomici allineati alla linea della cache evitano questo problema. Nota: multiple Atomics della stessa linea di cache continuerà a funzionare, ma sarà inefficiente
+1

La conclusione nell'ultimo paragrafo è errata. Supponiamo che la dimensione della linea della cache sia, diciamo, 32 byte. Quindi non è necessario allineare ai limiti di 32 byte. L'allineamento alla dimensione dei dati è sufficiente, a condizione che i dati non superino i 32 byte. Ad esempio, i dati a 4 byte possono essere allineati a 4 byte e non saranno mai a cavallo delle linee della cache. –

+0

@DavidHeffernan. Il problema di allineamento a cui mi riferisco, non nasce da un'unità dati atomica che si trova a cavallo di più linee di cache. Ma il problema si trova quando più variabili atomiche si trovano nella stessa linea della cache. Quando un'unità atomica viene spostata nello stato esclusivo, le unità atomiche non correlate nella stessa linea della cache diventeranno erroneamente esclusive (o chiuse in modo scorretto per l'uso). Quindi, per motivi di efficienza, è meglio disporre di atomici separati da linee di cache. (Funzionalmente non ci sarebbe alcuna differenza con l'allineamento a 4 byte) –

+1

Questo è il falso problema di condivisione, che è in qualche modo tangente al problema qui, penso che –

Problemi correlati