web-dev-qa-db-fra.com

Comment déterminer le nombre maximum à passer à l'option make -j?

Je veux compiler aussi vite que possible. Allez comprendre. Et voudrait automatiser le choix du nombre suivant le -j option. Comment puis-je choisir cette valeur par programme, par exemple dans un script Shell?

La sortie de nproc est-elle équivalente au nombre de threads avec lesquels je peux compiler?

make -j1make -j16

38
tarabyte

nproc donne le nombre de cœurs/threads de processeur disponibles, par exemple 8 sur un processeur quadricœur prenant en charge le SMT bidirectionnel.

Le nombre de travaux que vous pouvez exécuter en parallèle avec make à l'aide de l'option -j Dépend d'un certain nombre de facteurs:

  • la quantité de mémoire disponible
  • la quantité de mémoire utilisée par chaque make tâche
  • la mesure dans laquelle les travaux make sont liés aux E/S ou au processeur

make -j$(nproc) est un endroit décent pour commencer, mais vous pouvez généralement utiliser des valeurs plus élevées, tant que vous n'épuisez pas votre mémoire disponible et ne commencez pas à battre.

Pour les builds vraiment rapides, si vous avez assez de mémoire, je recommande d'utiliser un tmpfs, de cette façon la plupart des jobs seront liés au CPU et make -j$(nproc) fonctionnera aussi vite que possible.

42
Stephen Kitt

Malheureusement, même différentes parties d'une même build peuvent être optimales avec des valeurs de facteur j conflictuelles, selon ce qui est en cours de construction, comment, quelles ressources système sont le goulot d'étranglement à ce moment-là, ce qui se passe sur la machine de build, ce qui se passe dans le réseau (si vous utilisez des techniques de build distribuées), l'état/l'emplacement/les performances des nombreux systèmes de mise en cache impliqués dans une build, etc.

La compilation de 100 petits fichiers C peut être plus rapide que la compilation d'un seul gros fichier, ou vice versa. La construction d'un petit code très alambiqué peut être plus lente que la construction d'énormes quantités de code simple/linéaire.

Même le contexte de la construction est important - l'utilisation d'un facteur aj optimisé pour les builds sur des serveurs dédiés affinés pour des builds exclusifs et non superposés peut donner des résultats très décevants lorsqu'ils sont utilisés par des développeurs construisant en parallèle sur le même serveur partagé (chaque build peut prendre plus temps que tous combinés si sérialisés) ou sur des serveurs avec différentes configurations matérielles ou virtualisés.

Il y a aussi l'aspect de l'exactitude de la spécification de construction. Les constructions très complexes peuvent avoir des conditions de concurrence provoquant des échecs de construction intermittents avec des taux d'occurrence qui peuvent varier énormément avec l'augmentation ou la diminution du facteur j.

Je peux continuer encore et encore. Le fait est que vous devez réellement évaluer votre build dans votre contexte même pour lequel vous souhaitez optimiser le facteur j. Le commentaire de @Jeff Schaller s'applique: itérez jusqu'à ce que vous trouviez le meilleur ajustement. Personnellement, je partirais de la valeur nproc, j'essaierais d'abord vers le haut et vers le bas uniquement si les tentatives vers le haut montrent une dégradation immédiate.

Cela pourrait être une bonne idée de mesurer d'abord plusieurs constructions identiques dans des contextes supposés identiques juste pour avoir une idée de la variabilité de vos mesures - si elle est trop élevée, cela pourrait compromettre votre effort d'optimisation entier (une variabilité de 20% équivaudrait complètement à une amélioration de 10%/lecture de dégradation dans la recherche du facteur j).

Enfin, à mon humble avis, il est préférable d'utiliser un (adaptatif) jobserver s'il est pris en charge et disponible au lieu d'un facteur j fixe - il fournit systématiquement une meilleure performance de construction dans une plus large gamme de contextes.

8
Dan Cornilescu

La façon la plus simple est d'utiliser nproc comme ceci:

make -j`nproc`

La commande nproc renverra le nombre de cœurs sur votre machine. En l'enveloppant dans les ticks, la commande nproc s'exécutera en premier, retournera un nombre et ce nombre sera passé dans make.

Vous pouvez avoir une expérience anecdotique où le nombre de cœurs + 1 entraîne des temps de compilation plus rapides. Cela a davantage à voir avec des facteurs tels que les retards d'E/S, d'autres retards de ressources et d'autres contraintes de disponibilité des ressources.

Pour ce faire avec nproc+1, essaye ça:

make -j$((`nproc`+1))
8
010110110101

Si vous souhaitez écrire la commande make pour utiliser autant de travailleurs parallèles que vous avez de CPU virtuels, je suggère d'utiliser:

nproc | xargs -I % make -j%

Qui peut être écrite soit comme une commande autonome, soit comme une directive RUN dans Dockerfile (car Docker ne prend pas en charge les commandes imbriquées)

0
Maksym Ganenko
lscpu | grep "^CPU(" | awk '{print $2}'

Cela vous donne le nombre de cœurs de votre processeur.

0
Lynne