Estaba leyendo sobre el modelo de memoria que forma parte del próximo estándar C++ 0x. Sin embargo, estoy un poco confundido sobre algunas de las restricciones de lo que el compilador puede hacer, específicamente sobre cargas y tiendas especulativas.modelo de memoria C++ 0x y cargas/almacenes especulativos
Para empezar, algunas de las cosas relevantes:
Hans Boehm's pages about threads and the memory model in C++0x
Boehm, "Threads Cannot be Implemented as a Library"
Boehm and Adve, "Foundations of the C++ Concurrency Memory Model"
Boehm, "Concurrency memory model compiler consequences", N2338
Ahora, la idea básica es esencialmente "Consistencia Secuencial para Programas Libres de Raza de Datos", que parece ser un compromiso decente entre la facilidad de programación y la optimización del compilador y las oportunidades de hardware. Se define que una carrera de datos se produce si no se ordenan dos accesos a la misma ubicación de memoria por diferentes subprocesos, al menos uno de ellos almacena en la ubicación de memoria, y al menos uno de ellos no es una acción de sincronización. Implica que todo acceso de lectura/escritura a datos compartidos debe realizarse a través de algún mecanismo de sincronización, como mutexes u operaciones en variables atómicas (bueno, es posible operar en las variables atómicas con pedido de memoria relajado solo para expertos, pero predeterminado proporciona consistencia secuencial).
En vista de esto, estoy confundido acerca de las restricciones sobre cargas/tiendas espurias o especulativas en variables comunes compartidas. Por ejemplo, en N2338 tenemos el ejemplo
switch (y) {
case 0: x = 17; w = 1; break;
case 1: x = 17; w = 3; break;
case 2: w = 9; break;
case 3: x = 17; w = 1; break;
case 4: x = 17; w = 3; break;
case 5: x = 17; w = 9; break;
default: x = 17; w = 42; break;
}
que no se permite que el compilador de transformarse en
tmp = x; x = 17;
switch (y) {
case 0: w = 1; break;
case 1: w = 3; break;
case 2: x = tmp; w = 9; break;
case 3: w = 1; break;
case 4: w = 3; break;
case 5: w = 9; break;
default: w = 42; break;
}
ya que si y == 2 hay una escritura falsa ax que podría ser un problema si otro hilo estaba actualizando simultáneamente x. Pero, ¿por qué es esto un problema? Esta es una carrera de datos, que está prohibida de todos modos; en este caso, el compilador lo empeora escribiendo a x dos veces, pero incluso una sola escritura sería suficiente para una carrera de datos, ¿no? Es decir. un programa apropiado de C++ 0x necesitaría sincronizar el acceso a x, en cuyo caso ya no existiría la carrera de datos, y la tienda falsa tampoco sería un problema?
Estoy igualmente confundido sobre el Ejemplo 3.1.3 en N2197 y algunos de los otros ejemplos también, pero tal vez una explicación para el problema anterior también lo explique.
EDIT: La respuesta:
La razón por la cual las tiendas especulativos son un problema es que en el ejemplo instrucción switch anterior, el programador podría haber elegido para adquirir condicionalmente la cerradura proteger x sólo si y = 2! . Por lo tanto, la tienda especulativa podría introducir una raza de datos que no estaba allí en el código original, y la transformación está, por lo tanto, prohibida. El mismo argumento se aplica al ejemplo 3.1.3 en N2197 también.
Quizás uno para http://groups.google.com/group/comp.std.c++ –