c# - variable - Volatile viola su principal función?
volatile c# (3)
La documentación de MSDN es incorrecta. Eso ciertamente no es lo que hace volatile
. La especificación de C # le dice exactamente qué hace volatile
y obtener una "lectura nueva" o una "escritura confirmada" no es una de ellas. La especificación es correcta. volatile
solo garantiza la adquisición de vallas en las lecturas y las de liberación en las escrituras. Estos se definen como a continuación.
- adquirir-fence: una barrera de memoria en la que otras lecturas y escrituras no pueden moverse antes de la cerca.
- release-fence: una barrera de memoria en la que otras lecturas y escrituras no pueden moverse después de la cerca.
Trataré de explicar la tabla usando mi notación de flecha. Una flecha mark marcará una lectura volátil y una flecha ↑ marcará una escritura volátil. Ninguna instrucción puede moverse a través de la punta de flecha. Piense en la punta de flecha como empujando todo a la basura.
En el siguiente análisis utilizaré las variables; x
y y
. También asumiré que están marcados como volatile
.
Caso 1
Observe cómo la ubicación de la flecha después de la lectura de x
impide que la lectura de y
mueva hacia arriba. También tenga en cuenta que la volatilidad de y
es irrelevante en este caso.
var localx = x;
↓
var localy = y;
↓
Caso # 2
Observe cómo la ubicación de la flecha después de la lectura de x
evita que la escritura en y
mueva hacia arriba. También tenga en cuenta que la volatilidad de x
o y
, pero no de ambos, podría haberse omitido en este caso.
var localx = x;
↓
↑
y = 1;
Caso # 3
Observe cómo la ubicación de la flecha antes de la escritura en y
evita que la escritura en x
mueva hacia abajo. Tenga en cuenta que la volatilidad de x
es irrelevante en este caso.
↑
x = 1;
↑
y = 2;
Caso # 4
Observe que no hay una barrera entre la escritura en x
y la lectura de y
. Debido a esto, la escritura en x
puede flotar hacia abajo o la lectura de y
puede flotar hacia arriba. Cualquier movimiento es válido. Esta es la razón por la cual las instrucciones en el caso de lectura / escritura pueden ser intercambiadas
↑
x = 1;
var localy = y;
↓
Menciones notables
También es importante tener en cuenta que:
- El hardware x86 tiene una semántica volátil en las escrituras.
- La implementación de Microsoft de la CLI (y también de los sospechosos de Mono) tiene una semántica volátil en las escrituras.
- La especificación ECMA no tiene una semántica volátil en las escrituras.
Según MSDN :
La palabra clave volátil indica que un campo puede ser modificado por varios subprocesos que se ejecutan al mismo tiempo. Los campos que se declaran volátiles no están sujetos a optimizaciones del compilador que asumen el acceso por un solo hilo. Esto garantiza que el valor más actualizado esté presente en el campo en todo momento.
Por favor note la última oración:
Esto garantiza que el valor más actualizado esté presente en el campo en todo momento.
Sin embargo, hay un problema con esta palabra clave.
He read que puede cambiar el orden de las instrucciones:
First instruction Second instruction Can they be swapped? Read Read No Read Write No Write Write No Write Read Yes! <----
Esto significa que John establece un valor en un campo volátil, y más tarde Paul quiere leer el campo, ¡Paul está obteniendo el valor anterior!
¿Qué está pasando aquí? ¿No es ese el trabajo principal?
Sé que hay otras soluciones, pero mi pregunta es sobre la palabra clave volátil.
¿Debería yo (como programador) evitar el uso de esta palabra clave, debido a un comportamiento tan extraño?
Otro punto señalado por Joseph Albahari es que la arquitectura del proceso puede tener un impacto adverso en la volatilidad, es decir, AMD en particular puede hacer que se intercambien valores.
Como probablemente no tendrá idea de en qué tipo de sistema se ejecutará su aplicación en producción, es mejor evitar siempre la palabra clave volátil.
También un poco fuera de tema, siempre debe evitar la clase ReaderWriterLock, ya que en los sistemas de multiprocesador tiene una gran carga. Esto puede permitir múltiples bloqueos de escritura. Por favor, vea que aquí se toman simultáneamente, lo que provocará bloqueos en la aplicación que serán extremadamente difíciles de raíz.
Pues tienes razón. Está más elaborado en el book/article enhebrado de Joseph Albahari.
La documentación de MSDN indica que el uso de la palabra clave volátil garantiza que el valor más actualizado esté presente en el campo en todo momento. Esto es incorrecto, ya que, como hemos visto, se puede reordenar una escritura seguida de una lectura.
¿Debería yo (como programador) evitar el uso de esta palabra clave debido a un comportamiento tan extraño?
Se debe usar solo después de conocer este comportamiento extraño. No debe utilizarse como una palabra clave de Magic para recuperar los últimos valores en un entorno de multiproceso.
En mi opinión, se debe evitar el uso de palabras clave volátiles, ya que es probable que se descubran errores probables.