c++ - threads - pthread en c
¿La sincronización con `std:: mutex` es más lenta que con` std:: atomic(memory_order_seq_cst) `? (2)
La programación de Lockfree tiene que ver con las garantías de progreso : de más fuerte a más débil, son de espera , de bloqueo , de obstrucción y de bloqueo .
Una garantía es cara y tiene un precio. Cuantas más garantías desee, más pagará. En general, un algoritmo de bloqueo o estructura de datos (con un mutex, por ejemplo) tiene las mayores libertades y, por lo tanto, es potencialmente el más rápido. Un algoritmo libre de espera en el otro extremo debe usar operaciones atómicas en cada paso, lo que puede ser mucho más lento.
Obtener un candado es bastante barato, por lo que nunca debe preocuparse por eso sin una comprensión profunda del tema. Además, los algoritmos de bloqueo con mutexes son mucho más fáciles de leer, escribir y razonar. Por el contrario, incluso las estructuras de datos más simples y libres de bloqueos son el resultado de una investigación larga y enfocada, cada una de ellas vale uno o más doctores.
En pocas palabras, los algoritmos libres de bloqueo o espera cambian la peor latencia por la latencia media y el rendimiento. Todo es más lento, pero nada es siempre muy lento. Esta es una característica muy especial que solo es útil en situaciones muy específicas (como sistemas en tiempo real).
La razón principal para usar atomics sobre mutexes es que los mutex son caros pero con el modelo de memoria predeterminado para memory_order_seq_cst
es memory_order_seq_cst
, ¿no es esto tan costoso?
Pregunta: ¿Puede un programa simultáneo que usa bloqueos ser tan rápido como un programa simultáneo sin bloqueo?
Si es así, puede que no valga la pena el esfuerzo a menos que quiera usar memory_order_acq_rel
para memory_order_acq_rel
.
Editar: Puede que me esté perdiendo algo, pero el bloqueo no puede ser más rápido que estar libre de cerraduras porque cada bloqueo también tendrá que ser una barrera de memoria completa. Pero con el sistema sin cerradura, es posible usar técnicas que son menos restrictivas que las barreras de memoria.
Entonces, volviendo a mi pregunta, ¿el bloqueo es más rápido que el bloqueo basado en el nuevo estándar C ++ 11 con memory_model
defecto?
¿"True-free> = lock-based cuando se mide en el rendimiento" verdadero? Asumamos 2 hilos de hardware.
Edit 2: Mi pregunta no tiene que ver con las garantías de progreso, y quizás esté usando fuera de contexto "sin bloqueo".
Básicamente, cuando tiene 2 subprocesos con memoria compartida, y la única garantía que necesita es que si un subproceso está escribiendo, el otro no puede leer o escribir, mi suposición es que una simple operación de compare_and_swap
atómica y compare_and_swap
sería mucho más rápida que bloquear un mutex
Porque si un hilo ni siquiera toca la memoria compartida, terminarás bloqueando y desbloqueando una y otra vez sin ninguna razón, pero con las operaciones atómicas solo usas 1 ciclo de CPU cada vez.
En lo que respecta a los comentarios, un bloqueo de giro frente a un bloqueo de exclusión mutua es muy diferente cuando hay muy poca contención.
Un bloqueo tiende a requerir más operaciones que una simple operación atómica. En los casos más simples, memory_order_seq_cst será aproximadamente dos veces más rápido que el bloqueo porque el bloqueo tiende a requerir, como mínimo, dos operaciones atómicas en su implementación (una para bloquear, una para desbloquear). En muchos casos, lleva incluso más que eso. Sin embargo, una vez que empiece a aprovechar las órdenes de memoria, puede ser mucho más rápido porque está dispuesto a aceptar menos sincronización.
Además, a menudo verá que "los algoritmos de bloqueo siempre son tan rápidos como los algoritmos sin bloqueo". Esto es algo cierto. La idea básica es que si el algoritmo más rápido pasa a estar sin bloqueo, entonces el algoritmo más rápido sin la garantía de bloqueo es TAMBIÉN el mismo algoritmo. Sin embargo, si el algortihm más rápido requiere bloqueos, aquellos que exigen garantías de bloqueo deben buscar un algoritmo más lento.
En general, verá algoritmos sin bloqueo en algunos algoritmos de bajo nivel, donde el rendimiento de aprovechar códigos de operación especializados ayuda. En casi todos los demás códigos, el bloqueo es un rendimiento más que satisfactorio y mucho más fácil de leer.