when c++ c++11 atomic

when - c++, std:: atomic, ¿qué es std:: memory_order y cómo usarlos?



c++ atomic (5)

¿Alguien puede explicar qué es std :: memory_order en inglés simple, y cómo usarlos con std :: atomic <>?

Encontré la referencia y algunos ejemplos aquí, pero no entiendo en absoluto. http://en.cppreference.com/w/cpp/atomic/memory_order

Gracias.


¿Alguien puede explicar qué es std :: memory_order en inglés sencillo?

La mejor explicación de "llano inglés" que he encontrado para las diversas ordenaciones de memoria es el artículo de Bartoz Milewski sobre átomos atímicos relajados: http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/

Y la publicación de seguimiento: http://bartoszmilewski.com/2008/12/23/the-inscrutable-c-memory-model/

Pero tenga en cuenta que, si bien estos artículos son una buena introducción, son anteriores al estándar C ++ 11 y no le informarán todo lo que necesita saber para utilizarlos de manera segura.

y cómo usarlos con std :: atomic <>?

Mi mejor consejo para ti aquí es: no lo hagas . Los átomos atómicos relajados son (probablemente) la cosa más difícil y peligrosa en C ++ 11. Adhiera a std::atomic<T> con la ordenación de memoria predeterminada (consistencia secuencial) hasta que esté realmente seguro de que tiene un problema de rendimiento que puede resolverse utilizando las órdenes de memoria relajadas.

En el segundo artículo vinculado anteriormente, Bartoz Milewski llega a la siguiente conclusión:

No tenía idea de en qué me estaba metiendo cuando intentaba razonar acerca de los átomos atómicos débiles de C ++. La teoría detrás de ellos es tan compleja que está en el límite inutilizable. Se necesitaron tres personas (Anthony, Hans y yo) y una modificación en el estándar para completar la prueba de un algoritmo relativamente simple. ¡Imagina hacer lo mismo para una cola sin cerrojo basada en átomos atómicos débiles!


En resumen, su compilador y CPU pueden ejecutar instrucciones en orden diferente de cómo los ha escrito. Para un hilo único esto no es un problema, ya que aparecerá correcto. Para múltiples hilos en múltiples procesadores esto se convierte en un problema. La ordenación de memoria en C ++ restringe lo que su compilador / CPU puede hacer y soluciona dichos problemas.

Por ejemplo, si miras mi artículo sobre el bloqueo de doble verificación , puedes ver cómo el orden se confunde con ese patrón: menciona que el orden de la memoria atómica se puede usar para solucionarlo.

Acerca de la reordenación en sí misma también puede considerar la reordenación de la CPU . De nuevo, el compilador también puede estar haciendo reordenaciones.

Tenga en cuenta que cualquier documento sobre este tema (incluido el mío) ofrece hablar de escenarios teóricos. Las CPU más comunes, como x86, tienen garantías de pedido muy sólidas, por lo que una gran cantidad de pedidos explícitos simplemente no es necesaria. Por lo tanto, incluso si no usa los atómicos C ++ 11 correctos, su código probablemente aún funcione.

Como lo mencionó zvrba, el tema en realidad es bastante detallado. El documento de kernel de Linux sobre barreras de memoria también contiene mucha información detallada.



Los valores de std::memory_order permiten especificar restricciones detalladas en el orden de la memoria proporcionada por sus operaciones atómicas. Si está modificando y accediendo a variables atómicas de varios subprocesos, pasar los valores de std::memory_order a sus operaciones le permite relajar las restricciones en el compilador y procesador sobre el orden en que las operaciones en esas variables atómicas se vuelven visibles para otros hilos y los efectos de sincronización que esas operaciones tienen en los datos no atómicos en su aplicación.

El orden predeterminado de std::memory_order_seq_cst es el más limitado, y proporciona las propiedades "intuitivas" que podría esperar: si el hilo A almacena algunos datos y luego establece un indicador atómico usando std::memory_order_seq_cst , entonces si el hilo B ve que el indicador es configurado, a continuación, puede ver los datos escritos por el subproceso A. Los otros valores de ordenación de memoria no proporcionan necesariamente esta garantía y, por lo tanto, deben utilizarse con mucho cuidado.

La premisa básica es: no use nada más que std::memory_order_seq_cst (valor predeterminado) a menos que (a) realmente sepa lo que está haciendo y pueda demostrar que el uso relajado es seguro en todos los casos, y (b) su Profiler demuestra que la estructura de datos y las operaciones con las que pretende utilizar los pedidos relajados son un cuello de botella.

Mi libro, C ++ Concurrency in Action dedica un capítulo completo (45 páginas) a los detalles del modelo de memoria C ++, operaciones atómicas y las restricciones std::memory_order , y un capítulo adicional (44 páginas) al uso de operaciones atómicas para sincronización en bloqueo -Estructuras de datos libres, y las consecuencias de restricciones de orden relajadas.

Las entradas de mi blog sobre el algoritmo de Dekker y el algoritmo de Peterson para la exclusión mutua demuestran algunos de los problemas.


No. Una explicación de "inglés sencillo" toma 32 páginas y se puede encontrar here .

Si no quiere leer eso, puede olvidarse de ordenar la memoria porque la página a la que se vinculó dice que el orden predeterminado es ordenamiento secuencial consistente, que es "siempre hacer lo correcto" -setting.

Para utilizar cualquier otra configuración, realmente debe leer y comprender el documento anterior y los ejemplos que contiene.