multithreading - race - thread safe java
Palabra rasgada en x86 (3)
El x86 tiene cachés coherentes. El último procesador para escribir en una línea de caché adquiere todo y hace una escritura en el caché. Esto garantiza que los valores de un solo byte y de 4 bytes escritos en los valores correspondientes se actualicen atómicamente.
Eso es diferente de "es seguro". Si los procesadores solo escriben en bytes / DWORDS "propiedad" de ese procesador por diseño, entonces las actualizaciones serán correctas. En la práctica, desea que un procesador lea valores escritos por otros, y eso requiere sincronización.
También es diferente de lo que es "eficiente". Si varios procesadores pueden escribir en lugares diferentes en la línea de caché, entonces la línea de caché puede hacer ping-pong entre las CPU y eso es mucho más costoso que si la línea de caché se conecta a una única CPU y se queda allí. La regla habitual es colocar datos específicos del procesador en su propia línea de caché. Por supuesto, si solo va a escribir solo esa palabra, solo una vez, y la cantidad de trabajo es significativa en comparación con un movimiento de línea de caché, entonces su rendimiento será aceptable.
¿Bajo qué circunstancias es inseguro tener dos hilos diferentes escribiendo simultáneamente en elementos adyacentes de la misma matriz en x86? Entiendo que en algunas arquitecturas similares a DS9K con modelos de memoria demenciales esto puede causar desgarro de palabras, pero en x86 se pueden direccionar bytes individuales. Por ejemplo, en el lenguaje de programación D real
es un tipo de coma flotante de 80 bits en x86. ¿Sería seguro hacer algo como esto?
real[] nums = new real[4]; // Assume new returns a 16-byte aligned block.
foreach(i; 0..4) {
// Create a new thread and have it do stuff and
// write results to index i of nums.
}
Nota: Sé que, incluso si esto es seguro, a veces puede causar problemas falsos de intercambio con la memoria caché, lo que lleva a un rendimiento lento. Sin embargo, para los casos de uso que tengo en mente, las escrituras serán lo suficientemente infrecuentes para que esto no importe en la práctica.
Editar: No se preocupe por leer los valores que se escriben. La suposición es que habrá sincronización antes de que se lean los valores. Solo me importa la seguridad de escribir de esta manera.
Puede que me esté perdiendo algo, pero no preveo ningún problema. La arquitectura x86 solo escribe lo que necesita, no escribe nada fuera de los valores especificados. Cache-snooping maneja los problemas de caché.
Usted está preguntando acerca de x86 específicos, sin embargo, su ejemplo está en algún lenguaje de alto nivel. Su pregunta específica sobre D solo puede ser respondida por las personas que escribieron el compilador que está utilizando, o quizás por la especificación de lenguaje D. Java, por ejemplo, requiere que el acceso a los elementos de la matriz no cause desgarro.
Con respecto a x86, la atomicidad de las operaciones se especifica en la Sección 8.1 del Manual del desarrollador de software de Intel, Volumen 3A . De acuerdo con esto, las operaciones del almacén atómico incluyen: almacenar un byte, almacenar palabras alineadas con palabras y dword alineado con dword en todas las CPU x86. También especifica que en las CPU P6 y posteriores el acceso no alineado de 16, 32 y 64 bits a la memoria en caché dentro de una línea de caché es atómico.