volátil volatil significado que porque memoria eeprom duro disco c gcc inline-assembly

volatil - La diferencia entre asm, asm volátil y memoria de cloqueo



no volatil significado (3)

Al implementar estructuras de datos y código de tiempo sin bloqueo, a menudo es necesario suprimir las optimizaciones del compilador. Normalmente la gente hace esto usando una memory asm volatile con memory en la lista de clobber, pero a veces se ve tan asm volatile o simplemente una memoria de cloqueo de asm .

¿Qué impacto tienen estas declaraciones diferentes en la generación de código (particularmente en GCC, ya que es poco probable que sea portátil)?

Solo como referencia, estas son las variaciones interesantes:

asm (""); // presumably this has no effect on code generation asm volatile (""); asm ("" ::: "memory"); asm volatile ("" ::: "memory");


Consulte la página "Asm Extendida" en la documentación de GCC .

Puede evitar que se borre una instrucción asm escribiendo la palabra clave volatile después del asm . [...] La palabra clave volatile indica que la instrucción tiene importantes efectos secundarios. GCC no eliminará un asm volatile si es alcanzable.

y

Una instrucción asm sin ningún operando de salida se tratará de manera idéntica a una instrucción volátil de asm .

Ninguno de sus ejemplos tiene operandos de salida especificados, por lo que las formas asm volatile asm y asm volatile comportan de manera idéntica: crean un punto en el código que no se puede eliminar (a menos que se pruebe que no se puede alcanzar).

Esto no es lo mismo que no hacer nada. Vea esta pregunta para un ejemplo de un asm ficticio que cambia la generación de código: en ese ejemplo, el código que gira alrededor de un bucle 1000 veces se vectoriza en un código que calcula 16 iteraciones del bucle a la vez; pero la presencia de un asm dentro del bucle inhibe la optimización (el asm debe alcanzarse 1000 veces).

El trozo de "memory" hace que GCC asuma que cualquier memoria puede ser leída o escrita arbitrariamente por el bloque asm , por lo que evitará que el compilador vuelva a ordenar cargas o almacenes a través de ella:

Esto hará que GCC no guarde los valores de memoria en caché en los registros a través de la instrucción del ensamblador y no optimice los almacenes o cargas a esa memoria.

(Eso no impide que una CPU vuelva a ordenar cargas y almacenes con respecto a otra CPU, sin embargo, necesita instrucciones reales de barrera de memoria para eso).


Para completar la respuesta de Kevin Ballard, Visual Studio 2010 ofrece _ReadBarrier (), _WriteBarrier () y _ReadWriteBarrier () para hacer lo mismo (VS2010 no permite el ensamblado en línea para aplicaciones de 64 bits).

Estos no generan instrucciones, pero afectan el comportamiento del compilador. Un buen ejemplo está here

MemoryBarrier () genera lock or DWORD PTR [rsp], 0


asm ("") no hace nada (o al menos, se supone que no debe hacer nada).

asm volatile ("") tampoco hace nada.

asm ("" ::: "memory") es una valla de compilación simple.

asm volatile ("" ::: "memory") AFAIK es el mismo que el anterior. La palabra clave volatile le dice al compilador que no puede mover este bloque de ensamblaje. Por ejemplo, se puede sacar de un bucle si el compilador decide que los valores de entrada son los mismos en cada invocación. No estoy seguro de en qué condiciones el compilador decidirá que entiende lo suficiente sobre el conjunto para tratar de optimizar su ubicación, pero la palabra clave volatile suprime por completo. Dicho esto, me sorprendería mucho si el compilador intentara mover una declaración de asm que no tuviera entradas o salidas declaradas.

Incidentalmente, volatile también evita que el compilador elimine la expresión si decide que los valores de salida no se utilizan. Esto solo puede suceder si hay valores de salida, por lo que no se aplica a asm ("" ::: "memory") .