Qué es PTHREAD MUTEX ADAPTIVE NP


¿Dónde puedo encontrar documentación para mutexes pthread "adaptativos"? El símbolo PTHREAD_MUTEX_ADAPTIVE_NP está definido en mi sistema, pero la única documentación que puedo encontrar en línea no dice nada sobre qué es un mutex adaptativo, o cuándo es apropiado usarlo.

So... ¿qué es y cuándo debo usarlo?

Para referencia, mi versión de libc es:

GNU C Library (Ubuntu EGLIBC 2.15-0ubuntu10.5) stable release version 2.15, by Roland McGrath et al.
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.3.
Compiled on a Linux 3.2.50 system on 2013-09-30.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

Y "uname-a" da

Linux desktop 3.2.0-55-generic #85-Ubuntu SMP Wed Oct 2 12:29:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Author: laslowh, 2013-11-08

3 answers

Aquí tienes. Como lo leí, es un mutex brutalmente simple que no se preocupa por nada, excepto por hacer que el caso sin contención funcione rápidamente.

 2
Author: jthill,
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
2013-11-11 23:23:07

PTHREAD_MUTEX_ADAPTIVE_NP es algo que inventé mientras trabajaba en el papel de un colaborador de glibc para hacer que LinuxThreads sea más confiable y funcione mejor. LinuxThreads fue el predecesor de la biblioteca NPTL de glibc, originalmente desarrollada como una biblioteca independiente por Xavier Leroy, quien también es conocido como uno de los creadores de OCaml.

El mutex adaptativo sobrevivió a NTPL en forma esencialmente no modificada: el código es casi idéntico, incluyendo las constantes mágicas para el estimador suavizado y el spin máximo en relación con el estimador.

Bajo SMP, cuando vas a adquirir un mutex y ves que está bloqueado, puede ser subóptimo simplemente rendirse y llamar al núcleo para bloquear. Si el propietario de la cerradura solo mantiene la cerradura durante unas pocas instrucciones, es más barato esperar a la ejecución de esas instrucciones y luego adquirir la cerradura con una operación atómica, en lugar de gastar cientos de ciclos adicionales haciendo una llamada al sistema.

El los desarrolladores del kernel saben esto muy bien, que es una de las razones por las que tenemos spinlocks en el kernel de Linux para secciones críticas rápidas. (Entre las otras razones está, por supuesto, ese código que no puede dormir, porque está en un contexto de interrupción, puede adquirir spinlocks.)

La pregunta es, ¿cuánto tiempo debe esperar? Si giras para siempre hasta que se adquiere el bloqueo, eso puede ser subóptimo. Los programas de espacio de usuario no están bien escritos como el código del núcleo (cough). Podrían tener secciones críticas largas. También no pueden desactivar el preemption; a veces las secciones críticas explotan debido a un cambio de contexto. (Los subprocesos POSIX ahora proporcionan herramientas en tiempo real para hacer frente a esto: puede poner subprocesos en una prioridad en tiempo real y la programación FIFO y tal, además de configurar la afinidad del procesador.)

Creo que experimentamos con conteos de iteración fijos, pero luego tuve esta idea: ¿por qué debemos adivinar, cuando podemos medir. ¿Por qué no implementamos un estimador suavizado de la duración del bloqueo, de manera similar a lo que hacemos para el estimador de tiempo de espera de retransmisión TCP (RTO). Cada vez que giramos en un candado, debemos medir cuántas vueltas tomó en realidad para adquirirlo. Además, no debemos girar para siempre: quizás deberíamos girar solo como máximo el doble del valor actual del estimador. Cuando tomamos una medida, podemos suavizarla exponencialmente, en solo unas pocas instrucciones: tomar una fracción del valor anterior y del nuevo valor, y sumarlos juntos, que es lo mismo que agregar una fracción de su diferencia para volver a la estimador: digamos, estimator += (new_val - estimator)/8 para una mezcla de 1/8 a 7/8 entre el valor antiguo y el nuevo.

Puedes pensar en esto como un perro guardián. Supongamos que el estimador le dice que el bloqueo, en promedio, toma 80 giros para adquirir. Usted puede estar bastante seguro, entonces, que si usted ha ejecutado 160 giros, entonces algo está mal: el propietario de la cerradura está ejecutando algún caso excepcionalmente largo, o tal vez ha golpeado un fallo de página o de lo contrario se adelantó. En este punto el hilo de espera corta sus pérdidas y llamadas en el núcleo para bloquear.

Sin medición, no se puede hacer esto con precisión: no hay un valor de "talla única". Digamos que un límite fijo de 200 giros sería subóptimo en un programa cuyas secciones críticas son tan cortas que casi siempre se puede obtener un bloqueo después de esperar solo 10 giros. La función de bloqueo mutex se quemaría a través de 200 iteraciones cada vez que hay un tiempo de espera anómalo, en lugar de darse por vencido en, digamos, 20 y ciclos de ahorro.

Este enfoque adaptativo es especializado, en el sentido de que no funcionará para todos los bloqueos en todos los programas, por lo que se empaqueta como un tipo mutex especial. Por ejemplo, no funcionará muy bien para programas que bloquean mutexes durante largos períodos: períodos tan largos que se pierde más tiempo de CPU girando en los grandes valores del estimador que lo que habría sido al entrar en el núcleo. El enfoque tampoco es adecuado para uniprocesadores: todos los subprocesos, además del que está tratando de obtener el bloqueo, están suspendidos en el núcleo. El el enfoque tampoco es adecuado en situaciones en las que la equidad es importante: es un bloqueo oportunista. No importa cuántos otros hilos hayan estado esperando, por cuánto tiempo, o cuál sea su prioridad, un nuevo hilo puede venir y arrebatar el candado.

Si tiene un código muy bien comportado con secciones críticas cortas que son muy disputadas, y está buscando un mejor rendimiento en SMP, el mutex adaptativo puede valer la pena intentarlo.

 52
Author: Kaz,
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
2018-04-01 08:52:51

El símbolo se menciona allí:

Http://elias.rhi.hi.is/libc/Mutexes.html

"LinuxThreads soporta solo un atributo mutex: el tipo mutex, que es PTHREAD_MUTEX_ADAPTIVE_NP para mutexes "rápidos", PTHREAD_MUTEX_RECURSIVE_NP para mutexes "recursivos", PTHREAD_MUTEX_TIMED_NP para mutexes "temporizados", o PTHREAD_MUTEX_ERRORCHECK_NP para mutexes "comprobación de errores". Como indica el sufijo NP, esta es una extensión no portátil del estándar POSIX y no debe ser empleado en programas portátiles.

El tipo mutex determina lo que sucede si un subproceso intenta bloquear un mutex que ya posee con pthread_mutex_lock. Si el mutex es del tipo" rápido", pthread_mutex_lock simplemente suspende el hilo invocador para siempre. Si el mutex es del tipo "comprobación de errores", pthread_mutex_lock devuelve inmediatamente el código de error EDEADLK. Si el mutex es del tipo" recursivo", la llamada a pthread_mutex_lock devuelve inmediatamente con un código de retorno exitoso. El el número de veces que el hilo que posee el mutex lo ha bloqueado se registra en el mutex. El hilo propietario debe llamar a pthread_mutex_unlock el mismo número de veces antes de que mutex vuelva al estado desbloqueado.

El tipo mutex predeterminado es "timed", es decir, PTHREAD_MUTEX_TIMED_NP."

EDITAR: actualizado con información encontrada por jthill (gracias!)

Un poco más de información sobre las banderas mutex y el PTHREAD_MUTEX_ADAPTIVE_NP se puede encontrar aquí :

"El PTHRED_MUTEX_ADAPTIVE_NP es un nuevo mutex que está destinado a alta rendimiento en el sacrificio de la equidad e incluso los ciclos de CPU. Este mutex no transfiere la propiedad a un hilo en espera, sino más bien permite la competencia. Además, sobre un núcleo SMP, la operación de bloqueo utiliza el giro para volver a intentar el bloqueo para evitar el costo de inmediato descheduling."

Que básicamente sugieren lo siguiente: en caso de que sea deseable un alto thoughput, tal mutex se puede implementar requiriendo consideraciones adicionales de la lógica del hilo debido a su propia naturaleza. Tendrá que diseñar un algoritmo que pueda usar estas propiedades dando como resultado un alto rendimiento. Algo que load se equilibra desde dentro (a diferencia de "desde el núcleo") donde el orden de ejecución no es importante.

Había un libro muy bueno para linux/unix multithreading programming cuyo nombre se me escapa. Si lo encuentro, lo actualizaré.

 6
Author: Sebastien,
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
2013-11-15 21:30:54