OpenMP les threads s'exécutant sur le même processeur core
Je suis actuellement à la parallélisation du programme en utilisant openmp sur un 4-core phenom2. Cependant, j'ai remarqué que mon parallélisation ne fait rien pour la performance. Naturellement, j'ai supposé que j'ai raté quelque chose (falsesharing, la sérialisation dans les écluses, ...), cependant, j'ai été incapable de trouver quoi que ce soit. En outre, de l'Utilisation de l'UC, il semblait que le programme a été exécuté sur un seul core. De ce que j'ai trouvé sched_getcpu()
devrait me donner l'Id de la base au fil de l'exécution de l'appel est actuellement prévue. J'ai donc écrit le programme de test suivant:
#include <iostream>
#include <sstream>
#include <omp.h>
#include <utmpx.h>
#include <random>
int main(){
#pragma omp parallel
{
std::default_random_engine rand;
int num = 0;
#pragma omp for
for(size_t i = 0; i < 1000000000; ++i) num += rand();
auto cpu = sched_getcpu();
std::ostringstream os;
os<<"\nThread "<<omp_get_thread_num()<<" on cpu "<<sched_getcpu()<<std::endl;
std::cout<<os.str()<<std::flush;
std::cout<<num;
}
}
Sur ma machine cela donne le résultat suivant(les nombres aléatoires varient bien sûr):
Thread 2 on cpu 0 num 127392776
Thread 0 on cpu 0 num 1980891664
Thread 3 on cpu 0 num 431821313
Thread 1 on cpu 0 num -1976497224
De cette je suppose que tous les threads s'exécutent sur le même noyau (le noyau de l'un avec l'id 0). Pour être plus certain, j'ai aussi essayé l'approche de cette réponse. Les résultats sont les mêmes. De plus, en utilisant #pragma omp parallel num_threads(1)
ne pas rendre l'exécution plus lente (un peu plus rapide en fait), qui donne de la crédibilité à la théorie que tous les threads utilisent le même processeur, cependant, le fait que le processeur est toujours affiché comme 0
me fait une sorte de suspect. De plus j'ai vérifié GOMP_CPU_AFFINITY
qui était initialement pas ensemble, donc j'ai essayé de le définir à 0 1 2 3
, qui devrait lier chaque thread à un autre noyau de ce que je comprends. Cependant, cela ne voulait pas faire une différence.
Depuis développer sur un système windows, j'utilise linux avec virtualbox pour mon développement. Donc j'ai pensé que peut-être le système virtuel ne pouvais pas accéder à tous les cœurs. Cependant, la vérification des paramètres de virtualbox a montré que la machine virtuelle doit obtenir tous les 4 cœurs et de l'exécution de mon programme de test 4 fois dans le même temps semble utiliser les 4 coeurs à en juger par l'utilisation du processeur (et le fait que le système a été très ne répond pas).
Donc pour ma question est essentiellement ce qui se passe exactement ici. Plus au point:
Est ma déduction que tous les threads de même correctement? Si elle l'est, ce qui pourrait être les raisons de ce comportement?
OMP_NUM_THREADS
ne semble pas être ensemble, mais depuis, openmp permet de créer 4 threads, je ne pense pas que j'aurais besoin.bizarre je pense qu'il pourrait être quelque chose avec votre machine virtuelle, j'ai essayé le même code, même installé utmpx.h et il semblait bien fonctionner sur un 8 et 16 de base de la machine
J'ai lu quelque part que la machine virtuelle (OS invité) s'exécute comme un processus unique, à l'intérieur de votre système d'exploitation hôte. Cela pourrait-il être la cause du comportement que vous voyez?
La même chose se passe pour moi sur les 2 CPU x86-64 serveur avec Scientific Linux 6. Aucune IDE de la machine virtuelle ou en vue.
OriginalL'auteur Grizzly | 2012-02-21
Vous devez vous connecter pour publier un commentaire.
Après quelques essais, j'ai trouvé que le problème était que je commençais mon programme à partir de l'intérieur de l'IDE eclipse, ce qui semble définir l'affinité utiliser un seul noyau. J'ai pensé que j'ai eu le même problème lors du démarrage de l'extérieur de l'IDE, mais un essais répétés ont montré que le programme fonctionne très bien, lorsqu'il est démarré à partir du terminal, au lieu de partir de l'intérieur de l'ide.
OriginalL'auteur Grizzly
J'ai compilé ton programme à l'aide de g++ 4.6 sur Linux
La sortie a été, sans surprise:
Le fait que 4 threads sont lancés (si vous n'avez pas définir le nombre de threads en aucune façon, par exemple à l'aide de OMP_NUM_THREADS) devrait impliquer que le programme est en mesure de voir 4 utilisable Processeurs. Je ne devine pas pourquoi il n'est pas de les utiliser, mais je soupçonne un problème dans votre matériel/logiciel, dans certains variable d'environnement, ou dans les options du compilateur.
OriginalL'auteur baol
Vous devez utiliser
#pragma omp parallel for
Et oui, vous avez raison de ne pas avoir besoin de OMP_NUM_THREADS.
omp_set_num_threads(4);
doit aussi avoir fait amende.#pragma omp parallel for
, si je veux que le fils de faire des choses en dehors de la boucle (comme l'écriture de leur carte d'identité à la sortie)? Et comme je l'ai mentionné, il permet de créer 4 threads par défaut, le sembler juste pour être exécutées sur la même baseC'est vrai aussi. btw, si vous ne dites pas omp parallèle, alors pas de parallélisation qui se passe dans la boucle. Mais bien sûr, vous êtes à l'intérieur d'une section parallèle, donc.... La seule autre explication possible est, je pense, un manque de matériel de soutien pour votre virtualbox. Avez-vous essayé avec d'autres CPU? superuser.com/questions/33723/...
Je n'ai pas. Cependant, comme mentionné, il est possible d'utiliser tous les cœurs de la vbox, de sorte que le manque de soutien semble peu probable
OriginalL'auteur Nav
si vous êtes en cours d'exécution sur windows, essayez ceci:
c:\windows\system32\cmd.exe /C start /F affinité path\to\your\program.exe
/affinité 1 utilise CPU0
/affinité 2 utilise CPU1
/affinité 3 utilise CPU0 et CPU1
/affinité 4 utilise CPU2
/affinité F utilise tous les 4 cœurs
Convertir le nombre en hexadécimal, et de voir les bits de droite qui sont les cœurs à être utilisé.
vous pouvez vérifier l'affinité alors que de son fonctionnement à l'aide de gestionnaire de tâches.
OriginalL'auteur krishnaraj