web-dev-qa-db-fra.com

Pourquoi un mutex Pthread est-il considéré comme "plus lent" qu'un futex?

Pourquoi les mutiles POSIX sont-elles considérées comme plus lourdes ou plus lentes que les Fuex? Où vient-il les frais généraux du type Mutex Pthread? J'ai entendu dire que les mutiles Pthread sont basées sur des futex, et lorsqu'ils sont incontestés, ne apportent aucun appels dans le noyau. Il semble alors qu'un mutex de Pthread est simplement un "wrapper" autour d'un futex.

La surcharge est-elle simplement dans l'appel de la fonction-wrapper et la nécessité de la fonction mutex de "configurer" le FUTEX (c'est-à-dire fondamentalement la configuration de la pile pour l'appel de la fonction Mutex Pthread)? Ou y a-t-il des mesures de barrière de mémoire supplémentaires qui se déroulent avec le mutex de Pthread?

42
Jason

Parce qu'ils restent autant que possible dans les utilisateurs, ce qui signifie qu'ils nécessitent moins d'appels système, ce qui est intrinsèquement plus rapide car le passage du contexte entre l'utilisateur et le mode noyau est coûteux.

Je suppose que vous parlez de noya threads lorsque vous parlez de threads POSIX. Il est tout à fait possible d'avoir une implémentation entièrement utilisepace des threads POSIX qui ne nécessitent aucun appels système, mais avoir d'autres problèmes.

Ma compréhension est qu'un futex est à mi-chemin entre un fil POSIX de noyau et un fil d'utilisateurs POSIX.

8
Nektarios

Fuexes ont été créés pour améliorer la performance des mutiles Pthread. NPTL utilise des futurs, LinuxThreads prédéfinis Fuexes, que je pense, c'est là que vient la contrepartie "plus lente". Les mutiles NPTL peuvent avoir des frais généraux supplémentaires, mais cela ne devrait pas être beaucoup.

éditer : Le surcharge réel consiste essentiellement sur:

  • sélection de l'algorithme correct pour le type mutex (normal, récursif, adaptatif, vérification des erreurs; normal, robuste, héritage prioritaire, protégé de priorité), où le code suggère fortement au compilateur que nous utilisons probablement un mutex normal (donc il devrait transmettre que la logique de prévision de la succursale de la CPU),
  • et une rédaction du propriétaire actuel du mutex si nous parrions à le prendre, ce qui devrait normalement être rapide, car il réside dans la même ligne de cache que le verrou réel que nous venons de prendre, à moins que le verrou ne soit fortement soutenu et d'autres Le processeur a accédé à la serrure entre le moment où nous l'avons pris et lorsque nous avons tenté d'écrire le propriétaire (cette écriture est inutile pour les mutiles normales, mais nécessaire pour la vérification des erreurs et les mutiles récursifs).

Donc, quelques cycles (cas typique) à quelques cycles + une trajectoire de branche + un cache supplémentaire (très pire des cas).

30
ninjalj

La réponse courte à votre question est que les futurs sont connus pour être mis en œuvre aussi efficacement que possible, tandis qu'un mutex Pthread peut ou non être. Au minimum, un mutex Pthread a une surcharge associée à la détermination du type de mutex et de futexs. Donc, un futex sera presque toujours au moins aussi efficace qu'un mutex Pthread, jusqu'à ce que quelqu'un ne pense que la structure plus légère qu'un futex puis libère une mise en œuvre de Pthreads qui utilise cela pour son mutex par défaut.

14
David Schwartz

Les mutiles pthread techniquement parlant ne sont pas plus lentes ni plus rapides que les Fuex. Pthread n'est qu'une API standard, de sorte qu'ils sont lents ou rapides dépendent de la mise en œuvre de cette API.

Plus précisément dans les mutiles Linux Pthread sont implémentés comme futiles et sont donc rapides. En fait, vous ne voulez pas utiliser l'API Futex lui-même car il est très difficile à utiliser, ne dispose pas des fonctions d'emballage appropriées dans GLIBC et nécessite le codage dans l'assemblage qui serait non portable. Heureusement pour nous, les responsables GLIBC ont déjà codé tout cela pour nous sous le capot de l'API de Pthread Mutex.

Maintenant, parce que la plupart des systèmes d'exploitation n'a pas mis en œuvre Fuexes Les programmeurs peuvent généralement dire par Pthread Mutex, ce qui est de la performance que vous obtenez de la mise en œuvre habituelle des mutiles Pthread, qui est plus lente.

C'est donc un fait statistique que, dans la plupart des systèmes d'exploitation, POSIX conforme, le mutex Pthread est mis en œuvre dans l'espace du noyau et est plus lent qu'un futé. Sous Linux, ils ont la même performance. Il se pourrait qu'il y ait d'autres systèmes d'exploitation où les mutiles Pthread sont implémentés dans l'espace utilisateur (dans l'affaire non interprété) et ont donc une meilleure performance, mais je ne suis que conscient de Linux à ce stade.

11
Mark Veltzer

Sur AMD64, un futex est de 4 octets, tandis qu'un NPTL Pthread_Mutex_T est de 56 octets! Oui, il y a une surcharge importante.

1
user696732