10

¿En qué circunstancias no es seguro 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 para hacer algo como:Desgarro de palabras en x86

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, que a veces puede causar problemas de falsas compartir 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 como 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 allí será sincronización antes de que se lean los valores. Solo me importa la seguridad de escribiendo de esta manera.

+0

Supongo que está buscando escritos sucios de las direcciones adyacentes? – BCS

Respuesta

10

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 a "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 la 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 caché, entonces su rendimiento será aceptable.

+0

En cuanto a su punto de lectura: La idea era completar un gran conjunto en paralelo utilizando algo así como un mapa paralelo. La función de mapeo tomaría la mayor parte del tiempo, de modo que el tiempo dedicado a la escritura es insignificante, y las líneas de caché solo se compartirían cerca de los límites de las unidades de trabajo de todos modos. Antes de que se lean los valores de esta matriz, se usará una sincronización de algún tipo. – dsimcha

1

Me podría estar 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é.

1

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.

En cuanto a x86, la atomicidad de las operaciones se especifica en la Sección 8.1 de Intel's Software Developer's Manual Volume 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.