Pregunta

Sé que el .NETO modelo de memoria (en el .NET Framework;no compacto/micro/silverlight/mono/xna/lo-que-usted) garantiza que para ciertos tipos (más notablemente primitivo enteros y referencias) operaciones están garantizados para ser atómica.

Además, creo que el x86/x64 test-and-set de instrucciones (y Interlocked.CompareExchange) en realidad hace referencia a la memoria global de la ubicación, así que si sucede a otro Interlocked.CompareExchange iba a ver el nuevo valor.

Por último, creo que la volatile palabra clave es una instrucción para el compilador para propagar lee y graba lo antes posible para no reordenar las operaciones relativas a esta variable (a la derecha?).

Esto lleva a un par de preguntas:

  1. Son mis creencias sobre la correcta?
  2. Interlocked.Read no tiene una sobrecarga para int, sólo para anhela (que son 2 Palabras y por lo tanto no se suelen leer de forma atómica).Siempre he asumido que la .NETO modelo de memoria garantiza que el valor más reciente sería visto al leer enteros/referencias, sin embargo con el procesador almacena en caché, registros, etc.Estoy empezando a ver esto no puede ser posible.Entonces, ¿hay una manera de forzar la variable a ser re-fetched?
  3. Es volátil suficiente para resolver el problema anterior para los números enteros y las referencias?
  4. En los sistemas x86/x64 puedo asumir que...

Si hay dos entero global de las variables x e y, ambos se inicializa a 0, que si yo escribo:

x = 1;
y = 2;

Que NO el hilo se ve que x = 0 y y = 2 (es decir,las escrituras se producirá en orden).¿Este cambio si son volátiles?

¿Fue útil?

Solución

  • Sólo lee y escribe en variables que son como máximo 32 bits de ancho (y 64 bits de ancho x 64 de los sistemas) son atómicas. Todos significa esto es que no vas a leer un int y obtener un valor medio escribir. No lo hace media aritmética es atómica.
  • Las operaciones de interbloqueo también actúan como barreras de memoria, así que sí, Interlocked.CompareExchange verá el valor actualizado.
  • esta página . Volátil no significa que sean ordenados. Algunos compiladores pueden optar por no volver a pedir las operaciones sobre las variables volátiles, pero la CPU es libre de volver a pedir. Si desea detener la CPU de instrucciones de re-ordenamiento, utilizar una (completa) barrera de memoria.
  • el modelo de memoria asegura que lee y escribe son atómicas, y utilizando las palabras clave asegura volátiles que se lee siempre provienen de la memoria, no a partir de un registro. Por lo que ver el valor más reciente. Esto se debe a que las CPU x86 invalidará la caché cuando sea apropiado - véase este y esta . Asimismo, consulte InterlockedCompareExchange64 de cómo atómicamente leer valores de 64 bits.
  • Y finalmente, la última pregunta. La respuesta es un hilo de hecho, podría ver x = 0 y y = 2, y el uso de la palabra clave volátil que no cambia porque la CPU está libre para volver a pedir instrucciones. Se necesita una barrera de memoria.

Resumen:

  1. El compilador es libre de volver a pedir instrucciones.
  2. La CPU es libre de volver a pedir instrucciones.
  3. dimensionada-Word lecturas y escrituras son atómicos. Las operaciones aritméticas y otros no son atómicos porque implican una lectura, cálculo, a continuación, escribir.
  4. dimensionada-Word lee de la memoria será siempre recuperar el valor más reciente. Pero la mayoría de las veces no sé si en realidad estás leyendo la memoria.
  5. Detiene una barrera de memoria completo (1) y (2). La mayoría de los compiladores le permiten detener (1) por sí mismo.
  6. Los volátiles le asegura palabra clave está leyendo de la memoria -. (4)
  7. Las operaciones de interbloqueo (el prefijo de bloqueo) permite múltiples operaciones sean atómica. Por ejemplo, una lectura + escritura (InterlockedExchange). O una lectura + + comparar escritura (InterlockedCompareExchange). También actúan como barreras de memoria, por lo que (1) y (2) se detienen. Siempre escribir en la memoria (obviamente), por lo que (4) está garantizada.

Otros consejos

Llegaron a través de este hilo viejo.Las respuestas de Hans y wj32 son todas correctas, excepto por la parte en relación volatile.

Específicamente en cuanto a tu pregunta

En los sistemas x86/x64 puedo asumir que...Si hay dos mundial de variables de tipo integer x e y, ambos se inicializa a 0, que si Yo escribo: x = 1; y = 2;

Que NO el hilo se vea x = 0 y y = 2 (es decir,las escrituras de se producen en orden).¿Este cambio si ellos son volátiles?

Si y es volátil, el escribir a x se garantiza a suceder antes de que la escritura a y, por lo tanto no el hilo va a ver x = 0 y y = 2.Eso es porque la escritura no volátil variable tiene la "liberación de la semántica" (lógicamente equivalente a la emisión de un comunicado de cerca), es decir,todos los de lectura/escritura de instrucciones antes de que no se mueva pasar.(Esto implica que si x es volátil pero y es que no, usted todavía puede ver el inesperado x = 0 y y = 2.) Ver la descripción y el código de ejemplo en el C# spec para obtener más detalles.

No, la palabra clave volátil y la garantía de la atomicidad son demasiado débiles. Se necesita una barrera de memoria para asegurarse de que. Usted puede obtener una forma explícita con el método Thread.MemoryBarrier ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top