compiler c gcc

compiler - makefile



barrera de memoria gcc__sync_synchronize vs asm volátil(""::: "memoria") (2)

asm volatile("": : :"memory") se usa a menudo como una barrera de memoria (por ejemplo, como se ve en la macro de linux kernel barrier ()).

Esto suena similar a lo que hace el gcc __sync_synchronize .

¿Son estos dos similares? Si no, ¿cuáles son las diferencias y cuándo se usaría una sobre la otra?


Hay una diferencia significativa: la primera opción (asma en línea) en realidad no hace nada en el tiempo de ejecución, no se ejecuta ningún comando allí y la CPU no lo sabe. solo sirve en tiempo de compilación, para decirle al compilador que no mueva cargas o almacenes más allá de este punto (en cualquier dirección) como parte de sus optimizaciones. Se llama barrera SW.

La segunda barrera (sincronización incorporada) simplemente se traduciría en una barrera de hardware, probablemente una operación de valla (defensa / defensa) si está en x86 o sus equivalentes en otras arquitecturas. La CPU también puede hacer varias optimizaciones en tiempo de ejecución, la más importante es realizar operaciones fuera de servicio, esta instrucción le dice que se asegure de que las cargas o las tiendas no pueden pasar este punto y deben observarse en el lado correcto de el punto de sincronización.

Here''s otra buena explicación:

Tipos de barreras de memoria

Como se mencionó anteriormente, tanto los compiladores como los procesadores pueden optimizar la ejecución de las instrucciones de una manera que requiera el uso de una barrera de memoria. Una barrera de memoria que afecta tanto al compilador como al procesador es una barrera de memoria de hardware, y una barrera de memoria que solo afecta al compilador es una barrera de memoria de software.

Además de las barreras de memoria de hardware y software, una barrera de memoria puede restringirse a lecturas de memoria, escritura de memoria o ambas. Una barrera de memoria que afecta tanto a las lecturas como a las escrituras es una barrera de memoria completa.

También hay una clase de barrera de memoria que es específica para entornos de multiprocesador. El nombre de estas barreras de memoria tiene el prefijo "smp". En un sistema multiprocesador, estas barreras son barreras de memoria de hardware y en sistemas de procesador único, son barreras de memoria de software.

La macro barrier () es la única barrera de memoria de software, y es una barrera de memoria completa. Todas las demás barreras de memoria en el kernel de Linux son barreras de hardware. Una barrera de memoria de hardware es una barrera implícita de software.

Un ejemplo para cuando SW barrier es útil: considere el siguiente código:

for (i = 0; i < N; ++i) { a[i]++; }

Este bucle simple, compilado con optimizaciones, muy probablemente se desenrollaría y vectorizaría. Aquí está el código de ensamblado gcc 4.8.0 -O3 generó operaciones empaquetadas (vectoriales):

400420: 66 0f 6f 00 movdqa (%rax),%xmm0 400424: 48 83 c0 10 add $0x10,%rax 400428: 66 0f fe c1 paddd %xmm1,%xmm0 40042c: 66 0f 7f 40 f0 movdqa %xmm0,0xfffffffffffffff0(%rax) 400431: 48 39 d0 cmp %rdx,%rax 400434: 75 ea jne 400420 <main+0x30>

Sin embargo, al agregar su ensamblaje en línea en cada iteración, gcc no puede cambiar el orden de las operaciones más allá de la barrera, por lo que no puede agruparlas, y el ensamblaje se convierte en la versión escalar del ciclo:

400418: 83 00 01 addl $0x1,(%rax) 40041b: 48 83 c0 04 add $0x4,%rax 40041f: 48 39 d0 cmp %rdx,%rax 400422: 75 f4 jne 400418 <main+0x28>

Sin embargo, cuando la CPU ejecuta este código, se permite reordenar las operaciones "debajo del capó", siempre que no rompa el modelo de ordenación de memoria. Esto significa que la realización de las operaciones puede hacerse fuera de servicio (si la CPU lo admite, como la mayoría lo hace en estos días). Una valla HW habría impedido eso.


Un comentario sobre la utilidad de las barreras solo SW:

En algunos microcontroladores y otras plataformas integradas, es posible que tenga múltiples tareas, pero no hay sistema de caché o latencia de caché, y por lo tanto, no hay instrucciones de barrera de HW. Por lo tanto, debe hacer cosas como los bloqueos giratorios SW. La barrera SW evita las optimizaciones del compilador (combinación de lectura / escritura y reordenamiento) en estos algoritmos.