2011-04-04 9 views
5

Con respecto a la ordenación que describo a continuación, tengo algunas preguntas relacionadas.Garantías sobre la ordenación de memoria y la práctica de programación adecuada

  1. Dadas estas garantías de pedido, no necesito vallas explícitas en muchos lugares. Sin embargo, ¿cómo puedo expresar la "valla" al compilador, en particular a GCC? Es decir, la garantía de orden de programa solo se aplica siempre que el optimizador no reordene mi programa.

  2. ¿Hay nuevos chips comunes/populares en uso que tengan núcleos de propósito general que no ofrecen tales garantías?

  3. Estoy un poco confundido en C++ 0x con su idea de intercalar. ¿Debo utilizar la clase "atómica" para hacer uso de estas garantías, o hay algún otro aspecto en el borrador que también proporcione una forma de hacer uso de estas garantías?


Memoria pedidos

Tanto Intel como AMD, al menos con x86_64, garantía de que las cargas de memoria son secuenciales con respecto a las operaciones de la tienda hecho en un solo procesador. Es decir, si un procesador ejecuta estas tiendas:

  1. de tiendas El <-1
  2. tienda B <-2
  3. tienda C < - 3

En el momento en algún otro procesador ve C (3) se garantiza que también vea las tiendas anteriores A (1) y B (2). Ahora, la visibilidad entre los procesadores puede estar intercalada, pero la orden de la tienda de cualquier procesador dado también será secuencial.

También tienen garantías transitivos cuando el procesador 0 lee un valor almacenado por el procesador 1, a continuación, escribe un valor, que Procesador 2 leer el nuevo valor también debe ver que el valor de procesador 1.

Ignorar los casos especiales tratar con IO y dispositivos especiales. Solo me interesan las garantías generales de memoria: mi pedido aquí es el que más me interesa, ya que tiene la mayor importancia para los algoritmos concurrentes.

Respuesta

2

El dominio de este tipo de operaciones es esencial para construir sistemas operativos SMP y para comunicarse con ciertos tipos de hardware. La documentación del kernel de Linux proporciona una excelente visión general del tema junto con las soluciones específicas utilizadas por el kernel. Recomiendo echar un vistazo a su archivo memory-barriers.txt.

+0

Esta es una excelente descripción de la situación. –

0

Para las mayores garantías de que sus almacenes y cargas se ejecutan en precisamente el orden requerido, es posible que tenga que recurrir a asm bloques en el código y escribir sus mov instrucciones de manera explícita.

+0

Lamentablemente, esto no es necesario ni suficiente. A menos que se utilicen las instrucciones de barrera apropiadas, un núcleo de CPU será libre de reordenar las instrucciones en tiempo de ejecución si cree que puede salirse con la suya. Estas barreras también están disponibles como primitivas de mayor nivel, lo que anula la necesidad de recurrir al ensamblaje. – JohannesD

+0

@Johannes: su afirmación en su pregunta es que Intel especifica el orden de carga/almacén. Ahora, no lo he comprobado, pero si está en lo cierto, los efectos que quiere pueden garantizarse sin barreras CPU explícitas, de todos modos en x86. –

+0

@Zan Lynx: No, Johannes Dahlström tiene razón. El hecho de que usted ponga los movimientos en un orden particular no significa que terminarán en ese orden en su binario. El optimizador es libre de intercambiar las instrucciones, que (en x86) también intercambia las tiendas reales. – MSalters

0

Incluso si la plataforma garantiza la consistencia secuencial, se le siempre necesita algún tipo de sincronización para evitar condiciones de carrera cuando más de un hilo accede a la misma posición de memoria y al menos uno de ellos escribe en ella.C++ 0x ofrece tres maneras de implementar dicha sincronización:

  1. mutua exclusión - std::mutex y clases relacionadas
  2. las variables atómica - std::atomic<T>
  3. barreras de memoria explícita - std::atomic_thread_fence.

Los dos últimos aceptan un parámetrofin de memoria que permite una flexibilidad adicional (sólo para expertos!) En plataformas que no garantizan la consistencia secuencial, pero esto no es relevante en x86.

+0

Las garantías secuenciales * son * una forma de evitar carreras de datos. En un nivel bajo no estamos buscando usar * mutex * ya que es muy costoso. La cuestión es más cómo hacer uso de otras garantías de pedido de memoria de una manera independiente de la plataforma. –

+0

'atomic_thread_fence' es la parte de la cual no estoy muy claro en el estándar. La redacción parece implicar que el orden solo está garantizado para los tipos "atómicos", lo que sería casi inútil. Voy a hacer una pregunta más específica sobre eso. –

Cuestiones relacionadas