2017-10-09 12 views
0

Je suis confronté à un problème d'évolutivité sur un système multicœur. Mon application traite des données scientifiques en parallèle sur une machine à 4 cœurs physiques, 8 cœurs logiques avec hyperthreading activé. Nous lançons 8 JVM, une par noyau logique (nous passerons probablement à une JVM pour éviter le surcoût de la JVM)Comment détecter les problèmes d'évolutivité/de contention multicœur

Le problème est que l'évolutivité est presque linéaire jusqu'à 4 cœurs, mais nous obtenons à peine 10-20 % performance en ajoutant 4 "noyaux logiques" supplémentaires.

J'ai analysé le comportement des threads en profilant l'application et je ne vois pas de verrous ou de threads qui attendent trop. J'ai aussi vérifié avec pidstat et je ne vois pas par exemple un overhead de surcharge de contexte. Plus précisément, il n'y a presque pas de changement de contexte sur les processus Java. L'utilisation du processeur est super haute atteignant presque 100%, ce qui semble également correct.

Ma question est de savoir comment détecter et analyser la cause de cette mauvaise évolutivité après avoir dépassé le nombre de cœurs physiques. Quels outils et méthodes puis-je utiliser pour détecter la contention, où dois-je regarder et puis-je le réparer sans modifier l'architecture de l'application (par exemple en basculant vers une machine virtuelle Java par machine)

Merci

Répondre

0

Veuillez noter que l'hyper-threading ne double pas la capacité d'un seul core. En fait, certaines tâches sont moins performantes lorsque l'Hyper-Threading est activé. Le gain sera très dépendant de la nature du travail - plus d'étals de canalisation signifiera plus de possibilité de programmer un autre processus à la place du calage. A titre d'exemple: un accès totalement aléatoire à la mémoire donnerait plus en termes de gains de performance d'hyper-threading qu'un calcul intensif très rapide de cpu tout au sein de la même ligne de cache.

Voici les choses que deux threads matériels partagent et donc tout produiront affirmation limitant les gains:

  • Cache
  • ressources de prévision de la Direction
  • d'extraction d'instruction et le décodage
  • unités d'exécution (nombre entier et point flottant)

Une autre observation est que le fonctionnement le système doit supporter SMT/HT sinon il ne pourra pas programmer quoi que ce soit dans des cœurs supplémentaires ou programmer les mauvaises tâches.

Lorsqu'il est pris en charge par le système d'exploitation, il existe toujours une chance pour les conflits d'exploitation sur des éléments tels que les handles de fichiers ou les sockets réseau. Le plus 'embarrassingly parallélisable' la nature du travail, plus l'occasion de limiter cette contention. Si toutefois votre travail implique de lire et/ou d'écrire sur la même ressource système, vous aurez moins de gains.

Une fois que vous avez apporté toutes ces tâches dans 1 machine virtuelle Java, votre niveau de parallélisme va être:

int cores = Runtime.getRuntime().availableProcessors(); 
+0

Merci de votre réponse, il clarifie l'espace de problème. Je vais jeter un coup d'œil aux échecs de cache et aussi essayer de courir avec seulement des cœurs physiques pour avoir une idée. – greg