¿Por qué un pthread mutex se considera "más lento" que un futex?


¿Por qué se consideran los mutex POSIX más pesados o lentos que los futex? ¿De dónde viene la sobrecarga en el tipo pthread mutex? He oído que los mutexes de pthread se basan en futexes, y cuando no son impugnados, no hacen ninguna llamada al núcleo. Parece entonces que un pthread mutex es simplemente una "envoltura" alrededor de un futex.

Es la sobrecarga simplemente en la llamada function-wrapper y la necesidad de la función mutex para "configurar" el futex (es decir, básicamente la configuración de la pila para el pthread llamada a la función mutex)? ¿O hay algunos pasos adicionales de barrera de memoria que tienen lugar con el pthread mutex?

Author: Jeremy W. Sherman, 2011-06-16

5 answers

Porque permanecen en el espacio de usuario tanto como sea posible, lo que significa que requieren menos llamadas al sistema, lo que es inherentemente más rápido porque el cambio de contexto entre el modo de usuario y el modo de kernel es costoso.

Asumo que estás hablando de subprocesos kernel cuando hablas de subprocesos POSIX. Es completamente posible tener una implementación en espacio de usuario de hilos POSIX que no requieren llamadas al sistema, pero tienen otros problemas propios.

Mi entendimiento es que un futex está a medio camino entre un hilo POSIX del núcleo y un hilo POSIX del espacio de usuario.

 8
Author: Nektarios,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-15 21:14:04

Los futexes se crearon para mejorar el rendimiento de los mutexes pthread. NPTL utiliza futexes, LinuxThreads anteriores futexes, que creo que es donde viene la consideración" más lento". Los mutexes NPTL pueden tener algunos gastos adicionales, pero no debería ser mucho.

Editar: La sobrecarga real consiste básicamente en:

  • seleccionar el algoritmo correcto para el tipo mutex (normal, recursivo, adaptativo, comprobación de errores; normal, robusto, herencia de prioridad, protegido por prioridad), donde el código insinúa fuertemente al compilador que es probable que usemos un mutex normal (por lo que debería transmitir eso a la lógica de predicción de ramas de la CPU),
  • y una escritura del propietario actual del mutex si logramos tomarlo que normalmente debería ser rápido, ya que reside en la misma línea de caché que el bloqueo real que acabamos de tomar, a menos que el bloqueo esté fuertemente disputado y alguna otra CPU accediera al bloqueo entre el momento en que lo tomamos y cuando intentamos escribir el propietario (esto write es innecesario para mutexes normales, pero necesario para la comprobación de errores y mutexes recursivos).

Por lo tanto, unos pocos ciclos (caso típico) a unos pocos ciclos + una mala predicción de rama + un error de caché adicional (el peor de los casos).

 29
Author: ninjalj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 19:42:42

La respuesta corta a su pregunta es que se sabe que los futexes se implementan de la manera más eficiente posible, mientras que un mutex pthread puede o no serlo. Como mínimo, un pthread mutex tiene sobrecarga asociada con la determinación del tipo de mutex y los futexes no. Por lo tanto, un futex casi siempre será al menos tan eficiente como un mutex pthread, hasta y a menos que alguien piense en alguna estructura más liviana que un futex y luego lance una implementación de pthreads que la use por defecto mutex.

 13
Author: David Schwartz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-17 01:48:19

Técnicamente hablando, los mutexes de pthread no son más lentos o más rápidos que los futexes. pthread es solo una API estándar, por lo que si son lentos o rápidos depende de la implementación de esa API.

Específicamente en Linux, los mutexes de pthread se implementan como futexes y, por lo tanto, son rápidos. En realidad, no desea usar la API de futex en sí, ya que es muy difícil de usar, no tiene las funciones de envoltura adecuadas en glibc y requiere codificación en ensamblado que no sería portátil. Afortunadamente para nosotros, los mantenedores de glibc ya codificaron todo esto para nosotros bajo el capó de la API mutex de pthread.

Ahora, debido a que la mayoría de los sistemas operativos no implementaron futexes entonces los programadores generalmente significan que pthread mutex es el rendimiento que obtiene de la implementación habitual de pthread mutexes, que es, más lento.

Así que es un hecho estadístico que en la mayoría de los sistemas operativos que son compatibles con POSIX el pthread mutex se implementa en el espacio del kernel y es más lento que un futex. En Linux tienen el mismo rendimiento. Podría ser que hay otros sistemas operativos donde pthread mutexes se implementan en el espacio de usuario (en el caso no controvertido) y por lo tanto tienen un mejor rendimiento, pero solo soy consciente de Linux en este punto.

 8
Author: Mark Veltzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-29 19:55:31

En AMD64 un futex es de 4 bytes, mientras que un NPTL pthread_mutex_t es de 56 bytes! Sí, hay una sobrecarga significativa.

 1
Author: user696732,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-10 14:40:40