Reordenación simultánea de instrucciones de programación (JMM ordenado)

Reordenamiento de instrucciones

La secuencia de instrucciones que ejecuta la computadora después de haber sido compilada por el compilador del programa es generalmente una secuencia de instrucciones que emite el compilador del programa.En general, esta secuencia de instrucciones genera un resultado definitivo; para garantizar que cada ejecución tenga un resultado definitivo. Sin embargo, en circunstancias normales, para mejorar la eficiencia de la ejecución del programa, la CPU y el compilador permitirán la optimización de la instrucción de acuerdo con ciertas reglas

 

código fuente    ->    compilador de optimización reordenamiento    ->    Instrucción reordenamiento Paralelo    ->    reordenamiento de memoria del sistema    ->    instrucción ejecutada última

 

En un solo subproceso, asegúrese de que el resultado final de la ejecución del programa sea coherente con el resultado de la ejecución secuencial de código

El procesador debe considerar la dependencia de datos entre instrucciones al reordenar

Los subprocesos se ejecutan alternativamente en un entorno de subprocesos múltiples. Debido a la existencia de un reordenamiento del compilador, si las variables utilizadas en los dos subprocesos pueden garantizar la coherencia es incierto, y los resultados no pueden predecirse.

 

int a, b, x, y = 0;

Hilo 1 Hilo 2
x = a; y = b;
b = 1; a = 2;
 
x = 0   y = 0

Si el compilador realiza una optimización de reordenamiento en este código de programa, pueden ocurrir las siguientes situaciones

Hilo 1 Hilo 2
b = 1; a = 2;
x = a; y = b;
 
x = 2    y = 1

 

 

Cómo volátil prohíbe la reorganización de la instrucción

La palabra clave volátil evita que las instrucciones se reordenen al proporcionar una "barrera de memoria". Para implementar la semántica de la memoria volátil, el compilador inserta una barrera de memoria en la secuencia de instrucciones al generar código de bytes para prohibir tipos específicos de reordenamiento de procesador .

La mayoría de los procesadores admiten instrucciones de barrera de memoria.

Es casi imposible que el compilador encuentre una disposición óptima para minimizar el número total de barreras de inserción. Por esta razón, el modelo de memoria Java adopta una estrategia conservadora. La siguiente es una estrategia de inserción de barrera de memoria JMM basada en una estrategia conservadora:

inserte una barrera StoreStore frente a cada operación de escritura volátil.

Inserte una barrera StoreLoad después de cada operación de escritura volátil.

Inserte una barrera LoadLoad después de cada operación de lectura volátil.

Inserte una barrera LoadStore después de cada operación de lectura volátil.

 

¿Qué es una barrera de memoria?  

 

La barrera de memoria (o a veces llamada cerca de memoria) es una instrucción de CPU utilizada para controlar problemas de reordenamiento y visibilidad de memoria bajo ciertas condiciones. El compilador de Java también prohíbe reordenar de acuerdo con las reglas de la barrera de memoria.

Rol 1. Asegurar el orden de ejecución de operaciones específicas 2. Asegurar la visibilidad de la memoria de ciertas variables (volátil utiliza esta función para lograr la visibilidad de la memoria)

Las barreras de memoria se pueden dividir en los siguientes tipos de

barreras de LoadLoad: Para tales declaraciones Load1; Load2, antes de acceder a los datos que debe leer Load2 y a las operaciones de lectura posteriores, asegúrese de que los datos que va a leer Load1 sean leídos.

Barrera de StoreStore: para tales declaraciones Store1; StoreStore; Store2, antes de realizar Store2 y las operaciones de escritura posteriores, asegúrese de que las operaciones de escritura de Store1 sean visibles para otros procesadores.

Barrera de LoadStore: para tales sentencias Load1; LoadStore; Store2, antes de que Store2 y las operaciones de escritura posteriores se eliminen, asegúrese de que se lean los datos que va a leer Load1.

Barrera de StoreLoad: para tales declaraciones Store1; StoreLoad; Load2, antes de que se realice Load2 y todas las operaciones de lectura posteriores, asegúrese de que las escrituras de Store1 sean visibles para todos los procesadores. Su techo es la mayor de las cuatro barreras. En la mayoría de las implementaciones de procesador, esta barrera es una barrera omnipotente, que combina las funciones de las otras tres barreras de memoria.

 

 

Dado que tanto el compilador como el procesador pueden realizar la optimización de la reorganización de las instrucciones, si se inserta una barrera de memoria (Momory Barrier) entre las instrucciones, se le informará al compilador y a la CPU que no importa en qué orden no pueden reordenar con esta instrucción de Memory Barrier Es decir, al insertar una barrera de memoria, se prohíbe que las instrucciones antes y después de la barrera de memoria realicen una optimización de reordenamiento

Otra función de la barrera de memoria es forzar el vaciado de los diversos datos de caché de la CPU, de modo que cualquier subproceso en la CPU pueda leer la última versión de estos datos.

 

Supongo que te gusta

Origin www.cnblogs.com/chuzhong/p/12731889.html
Recomendado
Clasificación