web-dev-qa-db-fra.com

faire -j4 ou -j8

J'ai 4 processeurs et je compile une application gourmande en processeur, j'ai lu que l'utilisation de make avec le commutateur -j4 était recommandée pour OpenCV, devrais-je plutôt utiliser -j8 et quel est l'avantage de faire pour plusieurs processeurs?

39
user784435

Comme vous dites le -j L'indicateur indique à make qu'il est autorisé de générer la quantité de 'threads' fournie. Idéalement, chaque thread est exécuté sur son propre cœur/CPU, de sorte que votre environnement multicœur/CPU est utilisé au maximum.

make lui-même ne compile pas les fichiers source. Cela se fait par un compilateur (gcc). Le Makefile (entrée pour make) contient un ensemble de cibles. Chaque cible a un ensemble de dépendances (sur d'autres cibles) et des règles sur la façon de construire la cible. make lit le (s) Makefile (s) et gère toutes les cibles, dépendances et règles de construction. Outre la compilation des fichiers source, vous pouvez utiliser make pour effectuer n'importe quelle tâche qui peut être décrite par les commandes Shell.

Si vous définissez un nombre de threads autorisé trop élevé, il n'est pas possible de planifier chaque thread sur son propre noyau. Des commutateurs de programmation (contexte) supplémentaires sont nécessaires pour permettre à tous les threads de s'exécuter. Cette utilisation supplémentaire des ressources entraîne évidemment une baisse des performances.

Il existe plusieurs règles empiriques, mais je suppose que la définition du montant total à <number of cores> + 1 est le plus courant. L'idée derrière cela est que tous les cœurs ont leur propre thread et il y a un thread de gestion supplémentaire qui gère les cibles et qui est à côté d'être construit.

33
Veger

Les réponses ci-dessus sont toutes généralement correctes. Cependant, les détails sont un peu trompeurs. Par exemple, il n'est pas nécessaire d'ajouter un travail supplémentaire pour un "thread de gestion" (remarque: make n'est pas réellement multithread). make ne se considère jamais comme un travail aux fins de -j, donc, comme dit Huygens ci-dessus, si vous dites -j5 vous obtiendrez 5 tâches de compilation en cours d'exécution, pas 4 plus make.

La raison pour laquelle la plupart des gens utilisent [nombre de cœurs] + [un peu de remplissage] n'a rien à voir avec make ou ce dont il a besoin, mais plutôt avec la nature du compilateur. Un compilateur n'est vraiment qu'un outil de traduction de texte très compliqué: il lit du texte sous une forme et le convertit en "texte" (binaire) sous une autre forme. Une grande partie de cela (d'autant plus que votre langage devient plus complexe, comme C++), nécessite beaucoup de CPU. Mais cela nécessite également beaucoup d'E/S disque. Les E/S de disque sont lentes, donc pendant qu'un compilateur attend des données du disque, le noyau planifie l'exécution d'autres travaux. C'est pourquoi vous pouvez utilement avoir plus que le nombre de compilations de cœurs en cours d'exécution en même temps.

Quelle taille exacte pouvez-vous obtenir -j avant de commencer à voir des rendements décroissants (vos builds commencent en fait à ralentir, à un moment donné, avec plus de -j) dépend complètement de votre matériel, des types de builds que vous faites, etc. La seule façon de savoir avec certitude est l'expérimentation.

Cependant, [nombre de cœurs] + [quelques-uns] est généralement une bonne approximation.

63
MadScientist

Un processeur par thread plus un gestionnaire/chargeur. Étant donné qu'un thread qui effectue des opérations sur disque est techniquement presque inactif du point de vue du processeur, ajoutez-en un au nombre total de cœurs.

Si le processeur utilise l'hyperthreading, vous pouvez compter chaque cœur en toute sécurité comme deux cœurs et doubler le nombre de threads, de sorte qu'un processeur quadricœur Intel Core i7 devrait obtenir -j9 (huit cœurs virtuels plus le gestionnaire).

3
SF.

L'option -j N'est utilisée que pour accélérer la construction de l'application, elle détermine le nombre de travaux que make peut générer pour la construction. Vous pouvez soit définir -j<nb core> Soit encore plus haut -j<nb-core * 1.5> Pour que la compilation puisse se faire en parallèle.

Il n'a aucun impact sur le code compilé.

Pour un système à 4 cœurs, vous pouvez essayer make -j6. Si make peut exécuter des builds parallèles, il lancera jusqu'à 6 processus de compilation simultanés (par exemple 6 appels à gcc).

2
Huygens