2012-06-16 84 views
5

Leí el manual de Intel y encontré que hay un prefijo de bloqueo para las instrucciones, lo que puede evitar que los procesadores escriban en la misma ubicación de memoria al mismo tiempo. Estoy bastante emocionado al respecto. Supongo que podría usarse como hardware mutex. Así que escribí un fragmento de código para tener una oportunidad. El resultado es bastante frustrante. El bloqueo no es compatible con las instrucciones MOV o LEA. El manual dice que LOCK solo es compatible con ADD, ADC, Y, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NO, O, SBB, SUB, XOR, XADD y XCHG. Además, si el prefijo LOCK se usa con una de estas instrucciones y el operando de origen es un operando de memoria, se puede generar una excepción de código de operación indefinida (#UD).Prefijo LOCK de la instrucción Intel. ¿Cual es el punto?

Me pregunto por qué tantas limitaciones, tantas restricciones hacen que LOCK parezca inútil. No puedo usarlo para garantizar que una operación general de escritura no tenga datos sucios u otros problemas causados ​​por el paralelismo.

E.g. Escribí el código ++ (* p) en C. p es un puntero a una memoria compartida. El montaje correspondiente es como:

movl 28(%esp), %eax 
movl (%eax), %eax 
leal 1(%eax), %edx 
movl 28(%esp), %eax 
movl %edx, (%eax) 

añadí "LOCK" antes de "movl" y "leal", pero el procesador se queja "instrucción no válida". :-(Creo que la única manera de hacer que las operaciones de escritura serializados es el uso de software de exclusión mutua, ¿verdad?

+1

http://en.wikipedia.org/wiki/Fetch-and-add – Mysticial

+1

http://en.wikipedia.org/wiki/Compare-and-swap – Mysticial

+2

Un 'movl' en una dirección alineada es siempre atómico , entonces el bloqueo no haría ninguna diferencia. – hirschhornsalz

Respuesta

12

ciertamente no lo llamaría lock inútil. lock cmpxchg es la manera estándar para realizar compare-and-swap, que es el componente básico de muchos algoritmos de sincronización.

también, ver fetch-and-add.

+0

Gracias. Lo revisaré. – Sean

5

el propósito de lock es hacer operaciones atómica, no serializado. de esta manera, la CPU puede no tener preferencia antes de la operación surta efectos.

+0

Gracias por su respuesta. No estoy muy seguro acerca de estas terminologías. Supongo que atómico significa que la operación se realizará en un todo, sin interrupción, de lo contrario se cancelará. En este problema, incluso si "bloqueo de agregar" se realiza de forma atómica, si no significa que otro procesador no puede acceder a esa ubicación de memoria sigilosamente, al mismo tiempo. Entonces, ¿qué está haciendo "bloqueo" para evitar el acceso paralelo a la misma ubicación de memoria. Supongo que esto se llama serialización, haciendo que cada hilo acceda a la memoria uno por uno. – Sean

+1

Las operaciones atómicas son primitivas utilizadas * para * serialización, pero no se serializan ellas mismas; serialización se refiere a múltiples entidades * que realizan la misma operación * una a la vez, mientras que las operaciones atómicas realizan una operación arbitraria en un movimiento discreto, sin ser molestados por otros. –

0

Resulta útil cuando, en una máquina multiprocesador, hay dos procesos simultáneos que utilizan los mismos datos pero no pueden modificarlo simultáneamente.

Cuando uno de los procesos modifica los datos, utiliza el bloqueo de las instrucciones de modificación para que, cuando el segundo proceso intente modificarlo, tenga que esperar a que el primero finalice su trabajo antes de poder hacer propio en su turno.

Espero que esto ayude un poco.

2

Los procesadores x86 son conocidos por un diseño peludo con muchas funciones, muchas reglas e incluso más excepciones a todas esas reglas. Esto está relacionado con la larga historia de la familia.

Cuando los compiladores o las personas usan LOCK, siempre lo utilizan con todas sus limitaciones, a menudo en datos especialmente introducidos para realizar la sincronización entre hilos, en oposición a los datos de aplicación que los algoritmos eventualmente manipulan. Luego, uno adapta los protocolos de sincronización de subprocesos a lo que LOCK puede hacer por ellos, en lugar de viceversa.

El tipo general de instrucción que parece buscar se llama memory barriers. De hecho, x86 tiene varias instrucciones "modernas" de esta familia (MFENCE, LFENCE, SFENCE). Son valla completa, valla de carga y valla de la tienda, respectivamente. Sin embargo, su importancia en el conjunto de instrucciones está limitada a SSE, porque Intel garantiza la serialización de escrituras en la parte tradicional del conjunto de instrucciones, y esa es más o menos la razón por la cual esta arquitectura envejecida es un objetivo bastante fácil para la programación multiproceso.

Consulte también this answer para obtener más información.

0

En el ejemplo que nos proporcione, se puede utilizar un prefijo lock con una instrucción inc como esto (suponiendo p se encuentra en %eax):

lock inc (%eax) 

En los casos más generales, usted tiene que utilizar las cerraduras sin embargo.

Cuestiones relacionadas