Pourquoi plus de cœurs de processeur sur une machine virtuelle ralentiraient-ils les temps de compilation?

17

[edit # 2] Si quelqu'un de VMWare peut me frapper avec une copie de VMWare Fusion, je serais plus qu'heureux de faire la même chose qu'une comparaison VirtualBox vs VMWare. D'une certaine manière, je soupçonne que l'hyperviseur VMWare sera mieux réglé pour l'hyperthreading (voir aussi ma réponse)

Je vois quelque chose de curieux. À mesure que j'augmente le nombre de cœurs sur ma machine virtuelle Windows 7 x64, le temps de compilation global augmente au lieu de diminuer. La compilation est généralement très bien adaptée au traitement parallèle, car dans la partie centrale (mappage post-dépendance), vous pouvez simplement appeler une instance de compilateur sur chacun de vos fichiers .c / .cpp / .cs / any pour créer des objets partiels à prendre par l'éditeur de liens. plus de. J'aurais donc imaginé que la compilation serait en fait très bien adaptée à # de cœurs.

Mais ce que je vois c'est:

  • 8 cœurs: 1,89 s
  • 4 cœurs: 1,33 s
  • 2 cœurs: 1,24 s
  • 1 cœur: 1,15 s

Est-ce simplement un artefact de conception dû à l'implémentation de l'hyperviseur d'un fournisseur particulier (type2: virtualbox dans mon cas) ou quelque chose de plus omniprésent sur plus de machines virtuelles pour rendre les implémentations de l'hyperviseur plus simples? Avec autant de facteurs, je semble être en mesure de faire des arguments pour et contre ce comportement - donc si quelqu'un en sait plus que moi sur ce sujet, je serais curieux de lire votre réponse.

Merci Sid

[ modifier: adresser les commentaires ]

@MartinBeckett: Les compilations à froid ont été supprimées.

@MonsterTruck: Impossible de trouver un projet open source à compiler directement. Ce serait génial, mais je ne peux pas foutre mon env dev maintenant.

@Mr Lister, @philosodad: Avoir 8 threads hw, utilisant VirtualBox, donc devrait être un mappage 1: 1 sans émulation

@Thorbjorn: J'ai 6,5 Go pour la machine virtuelle et un petit projet VS2012 - il est très peu probable que j'échange dans / hors la corbeille du fichier d'échange.

@All: Si quelqu'un peut pointer vers un projet VS2010 / VS2012 open source, cela pourrait être une meilleure référence communautaire que mon projet VS2012 (propriétaire). Orchard et DNN semblent avoir besoin d'un ajustement de l'environnement pour être compilés dans VS2012. J'aimerais vraiment voir si quelqu'un avec VMWare Fusion le voit aussi (pour le compartimentage VMWare vs VirtualBox)

Détails du test:

  • Matériel: Macbook Pro Retina
    • CPU: Core i7 @ 2.3Ghz (quad core, hyper threaded = 8 cores in windows task manager)
    • Mémoire: 16 Go
    • Disque: 256 Go SSD
  • Système d'exploitation hôte: Mac OS X 10.8
  • Type de VM: VirtualBox 4.1.18 (hyperviseur de type 2)
  • Système d'exploitation invité: Windows 7 x64 SP1
  • Compilateur: VS2012 compile une solution avec 3 projets Azure C #
    • Compilation de la mesure du temps par le plugin VS2012 appelé «VSCommands»
    • Tous les tests sont exécutés 5 fois, les 2 premiers tests sont rejetés, les 3 derniers en moyenne
DeepSpace101
la source
9
Probablement les E / S de fichiers le ralentissant avec de multiples tâches et l'accès au disque étant au lecteur virtualisé
Martin Beckett
3
Je voudrais reproduire cela sur ma propre machine. Pouvez-vous télécharger un exemple de projet quelque part? Je soupçonne que la machine virtuelle joue des tours ici. Essayez de démarrer Windows nativement (Bootcamp) et voyez si vous observez le même comportement - je doute que vous le fassiez.
Apoorv Khurasia
1
Que compilons-nous ici? Beaucoup de temps, la surcharge de parallélisation d'une tâche ne porte ses fruits que lorsque vous atteignez une certaine échelle. Voyez comment la compilation d'apache ou de ravendb fonctionne.
Wyatt Barnett du
2
Vous manquez probablement de mémoire dans votre machine virtuelle afin qu'elle commence à s'échanger.
1
La même chose m'est arrivée auparavant avec Java utilisant Maven 3.x pour compiler sur un i3. Le laisser par défaut à "4" threads était beaucoup plus lent, près de 50% plus lent, que de lui dire explicitement de n'utiliser que 2 cœurs. Je pense que cela a quelque chose à voir avec le changement de contexte hyper-threading et le chevauchement des E / S.

Réponses:

12

Réponse: Il ne ralentit pas, il évolue avec # de cœurs CPU. Le projet utilisé dans la question d'origine était «trop petit» (c'est en fait une tonne de développement mais petit / optimisé pour un compilateur) pour profiter des avantages de plusieurs cœurs. Semble au lieu de planifier comment répartir le travail, engendrer plusieurs processus de compilation, etc., à cette petite échelle, il est préférable de marteler le travail en série dès le départ.

Ceci est basé sur la nouvelle expérience que j'ai faite sur la base des commentaires de la question (et de ma curiosité personnelle). J'ai utilisé un plus grand projet VS - le code source d' Umbraco CMS car il est grand, open source et on peut directement charger le fichier de solution et reconstruire (indice: charger umbraco_675b272bb0a3\src\umbraco.slndans VS2010 / VS2012).

MAINTENANT, ce que je vois est ce que j'attends, c'est-à-dire que les compilations évoluent! Eh bien, jusqu'à un certain point puisque je trouve:

Tableau des résultats

Points à retenir:

  • Un nouveau cœur de machine virtuelle se traduit par un nouveau thread OS X dans le processus VirtualBox
  • Les temps de compilation évoluent comme prévu (les compilations sont suffisamment longues)
  • À 8 cœurs de machine virtuelle, l'émulation de cœurs peut entrer en jeu dans VirtualBox car la pénalité est énorme (50% de réussite)
  • Ce qui précède est probablement dû au fait qu'OS X ne peut pas présenter 4 cœurs hyper-threadés (8 h / w thread) en tant que 8 cœurs à VirtualBox

Ce dernier point m'a amené à surveiller l'historique du CPU sur tous les cœurs via 'Activity Monitor' (historique du CPU) et ce que j'ai trouvé était

Graphique historique du processeur OS X

Points à retenir:

  • Au niveau d'un cœur de machine virtuelle, l'activité semble être en train de sauter sur les 4 cœurs HW. Il est logique de répartir uniformément la chaleur au niveau du cœur.

  • Même avec 4 cœurs virtuels (et 27 threads VirtualBox OS X ou ~ 800 threads OS X au total), seuls les threads HW (0,2,4,6) sont presque saturés, tandis que les threads HW impairs (1,3,5,7) sont presque à 0%. Il est plus probable que le planificateur fonctionne en termes de cœurs HW et NON de threads HW, donc je suppose que le noyau / planificateur OSX 64 bits n'est pas optimisé pour le processeur hyper threadé? Ou en regardant la configuration du noyau 8VM, peut-être qu'il commence à les utiliser à un taux d'utilisation élevé du processeur Quelque chose de drôle en va un ... eh bien, c'est une question distincte pour certains développeurs Darwin ...

[modifier]: J'adorerais essayer la même chose dans VMWare Fusion. Il y a de fortes chances que ce ne soit pas si mauvais. Je me demande s'ils présentent cela comme un produit commercial ...

Bas de page:

Dans le cas où les images disparaissent, le calendrier de compilation est (texte, moche!)

Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%
DeepSpace101
la source
Je soupçonne que la baisse entre 4 et 8 est une combinaison de la machine virtuelle non optimisée pour HT, et HT n'étant en aucun cas égal à deux fois plus de cœurs (au mieux une augmentation de 30% des performances, généralement beaucoup moins).
Daniel B
@DanielB: À 4 => 8 cœurs, le problème n'est pas seulement qu'il s'agit d'un simple boost de + 30% (vs + 100%) comme vous l'avez suggéré - c'est que les performances sont en fait de -50%. Si les threads matériels étaient totalement «morts / inutiles» et que le travail était détourné vers les autres cœurs, le delta de performance serait de 0. Donc, je serais plus enclin à dire que c'est la conception de l'hyperviseur VirtualBox type 2. Je me demande comment VMWare Fusion est ...
DeepSpace101
"Sur un cœur de machine virtuelle, l'activité semble être en train de se propager sur les 4 cœurs HW. Il est logique de répartir la chaleur uniformément au niveau du cœur" - pas nécessairement, il est généralement préférable de reprogrammer sur le même cœur (pour le cache, etc.) mais l'hyperviseur en choisit simplement un chez randon, ou le noyau le moins utilisé, car il pense que c'est un traitement à usage général où d'autres processus utilisent ces cœurs. Dans ce cas, l'optimisation de l'ordonnanceur fonctionne contre vous (mais d'une manière très mineure)
gbjbaanb
@Sid a convenu, je souligne simplement qu'avec HT, vous obtiendrez (considérablement) des rendements décroissants beaucoup plus tôt que vous ne le pensez, si vous supposiez qu'il s'agissait en fait d'une amélioration de 100%. Dans ce cas, il pourrait facilement y avoir des conflits pour votre disque dur à l'origine de cela, d'où ma suggestion précédente pour certains repères artificiels du processeur.
Daniel B
6

Il n'y a qu'une seule raison possible pour que cela se produise, c'est que vos frais généraux dépassent vos gains.

Vous pouvez émuler les multiples cœurs, plutôt que d'attribuer des cœurs réels ou même des processus ou même des threads de la machine hôte. Cela me semble très probable et va évidemment vous donner une accélération négative.

L'autre possibilité est que le processus lui-même ne se parallélise pas bien, et même tenter de le paralléliser vous coûte plus cher en frais de communication que vous n'en gagnez.

philosodad
la source
your overhead is exceeding your gains: Vrai mais cela couvre à peu près tout sans savoir ce qui en est vraiment la cause :) ... J'utilise VirtualBox et j'ai les cœurs physiques, donc supposé que le mappage devrait être 1: 1 sans émulation. Je vais chercher un GRAND open source VS2012 pour que d'autres puissent le référencer aussi ... brb
DeepSpace101
@Sid selon cette réponse superuser.com/a/297727, la machine virtuelle virtualbox doit utiliser les cœurs hôtes de manière appropriée. Mais je vérifierais toujours ce qui se passe sur l'hôte, pour m'assurer que le comportement attendu se produit.
philosodad
0

Tu n'es pas seul ...

La même chose m'est arrivée auparavant avec Java utilisant Maven 3.x pour compiler sur un i3. Le laisser par défaut à "4" threads était beaucoup plus lent, près de 50% plus lent, que de lui dire explicitement de n'utiliser que 2 cœurs.

Je pense que cela a quelque chose à voir avec le changement de contexte hyper-threading et le chevauchement des E / S.

Cela a du sens lorsque vous commencez à y penser. Vous pouvez prouver ce qui cause la dégénérescence des résultats avec un bon outil de profilage à l'échelle du système.


la source