2010-11-05 11 views

Respuesta

28

remito a la sección 10.5.3 de la especificación, que establece:

Para los campos no volátiles, optimización técnicas que reordenan las instrucciones pueden conducir a resultados inesperados y impredecibles en multi- programas enrutados que acceden a los campos sin sincronización como proporcionados por la instrucción de bloqueo (§8.12). Estas optimizaciones pueden ser realizadas por el compilador, por el sistema de tiempo de ejecución o por hardware.Para campos volátiles, tales reordenamiento optimizaciones están restringidas:

Un lectura de un campo volátil se llama una lectura volátil . Una lectura volátil tiene "adquirir semántica"; es decir, es garantizado que ocurre antes de cualquier referencia a la memoria que se produce después de en la secuencia de instrucciones.

A escritura de un campo volátil se llama escritura volátil. Una escritura volátil tiene "semántica de publicación"; es decir, está garantizado después de cualquier referencia de memoria anterior a la instrucción de escritura en la secuencia de instrucciones .

Estas restricciones garantizan que todas las discusiones observarán volátiles escrituras realizadas por cualquier otro hilo en el orden en el que fueron realizado. No es necesario que una implementación conforme proporcione un único pedido total de escrituras volátiles como visto desde todos los hilos de ejecución.

Leer que con extremo cuidado si tiene alguna intención de volver a hacer un campo volátil. Si no hace completamente y completamente entiende todas las implicaciones de la semántica volátil, entonces no intente usarlas. Por lo general, es mucho mejor usar un bloqueo, que automáticamente le proporciona suficientes barreras de memoria para garantizar la semántica de adquisición y liberación necesaria. Recuerde, las cerraduras son realmente caras cuando se disputan.

+2

bueno, esa fue una gran explicación. (Y) –

+0

@Shimmy: Usted es perfectamente capaz de encontrar la especificación sin mi ayuda. –

+0

Pero no especificación 10.5.3 :) – Shimmy

4

MSDN resumirá mejor que yo ....

"La palabra clave volátil indica que un campo puede ser modificado por múltiples hilos que se están ejecutando al mismo tiempo. Los campos que se declaró volátiles no están sujetas a las optimizaciones del compilador que asumen el acceso por un solo hilo. Esto asegura que el valor más actualizado esté presente en el campo en todo momento ".

http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

7

volátil se utiliza para una variable que puede cambiar sin su acción, mientras que el código se está ejecutando. Le dice al compilador que escriba el ensamblaje de forma tal que nunca lo guarde en caché, sino que debe asegurarse de leerlo antes de cada uso.

Un ejemplo de algo que sería volátil sería un registro de hardware que su código tiene memoria asignada y está leyendo para determinar cuándo se establece un indicador. El hardware puede establecer el valor mientras se ejecuta el código y, sin usar la palabra clave volátil, no notaría este cambio, ya que el ensamblado nunca verificaría realmente el valor.

6

volátil es una sugerencia para el compilador (y compilador NGEN/JIT) que el valor de esta variable puede cambiar en cualquier momento, y por lo tanto optimizaciones alrededor de acceder a la variable al almacenar en caché el valor localmente volátil estar deshabilitado .

Consideremos el siguiente código:

If (UserName == "") 
    // do something 
If (UserName == "Fred") 
    // do something 

Si volátil no estaba presente, el compilador puede generar IL donde almacena la referencia en la pila para la primera comparación y que reutiliza para la segunda. Sin embargo, agregar volátil le dice al compilador que la referencia puede ser modificada por otro hilo, forzándolo a generar IL que no reutilizará la copia de la pila de la primera comparación.

+0

hmm, quieres decir, cada vez que accedes a una variable, generará una nueva IL en lugar de usar la copia de la pila, ¿verdad? –

+0

Sí, si está presente la volatilidad, el compilador generará nuevas instrucciones IL para obtener el valor de campo para cada acceso de campo. Si no se encuentra volátil, el obligado puede omitir ese IL para el segundo y posterior acceso completo. –

+0

Vale la pena señalar que esto solo es necesario con aplicaciones de subprocesos múltiples. Un hilo puede leer UserName, luego la CPU cambia al otro hilo, actualiza UserName, luego la CPU vuelve a encenderse. el primer hilo ahora tiene una versión anterior de UserName a menos que vuelva a verificarlo. –

2

Es nada más que decirle al compilador que esta variable va a cambiar su valor en cualquier momento por medio de cualquier cosa y compilador no debe hacer ninguna suposición sobre esta variable.

Normalmente, el compilador supondrá que alguna variable será constante durante el tiempo de ejecución. Esto puede provocar un error al verificar un valor de registor repetidamente. Debido a que el valor de registro puede ser cambiado por cualquier cosa. Por lo tanto, para este tipo de variables, el debe declararse como "volátil" y debe verificarse cada vez que aparezca en el código sin suponerlo.

Cuestiones relacionadas