2017-08-31 2 views
1

J'ai rencontré un phénomène intéressant que je ne parviens pas à expliquer. Je n'ai pas trouvé de réponse en ligne, car la plupart des articles traitent de la mise à l'échelle faible et donc des frais généraux de communication.Augmenter le nombre de processeurs diminue les performances, avec une charge CPU constante et aucune communication

Voici un petit morceau de code pour illustrer le problème. Cela a été testé dans différentes langues avec des résultats similaires, d'où les multiples étiquettes.

#include <mpi.h> 
#include <stdio.h> 
#include <time.h> 

int main() { 

    MPI_Init(NULL,NULL); 

    int wsize; 
    MPI_Comm_size(MPI_COMM_WORLD, &wsize); 

    int wrank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank); 


    clock_t t; 

    MPI_Barrier(MPI_COMM_WORLD); 

    t=clock(); 

    int imax = 10000000; 
    int jmax = 1000; 
    for (int i=0; i<imax; i++) { 
     for (int j=0; j<jmax; j++) { 
      //nothing 
     } 
    } 

    t=clock()-t; 

    printf(" proc %d took %f seconds.\n", wrank,(float)t/CLOCKS_PER_SEC); 

    MPI_Finalize(); 

    return 0; 

} 

Maintenant, comme vous pouvez le voir, la seule partie chronométrée ici est la boucle. Par conséquent, avec des processeurs similaires, sans hyperthreading, et suffisamment de RAM, augmenter le nombre de processeurs devrait produire exactement le même temps.

Cependant, sur ma machine qui est de 32 cœurs avec RAM 15GiB,

mpirun -np 1 ./test 

donne

proc 0 took 22.262777 seconds. 

mais

mpirun -np 20 ./test 

donne

proc 18 took 24.440767 seconds. 
proc 0 took 24.454365 seconds. 
proc 4 took 24.461191 seconds. 
proc 15 took 24.467632 seconds. 
proc 14 took 24.469728 seconds. 
proc 7 took 24.469809 seconds. 
proc 5 took 24.461639 seconds. 
proc 11 took 24.484224 seconds. 
proc 9 took 24.491638 seconds. 
proc 2 took 24.484953 seconds. 
proc 17 took 24.490984 seconds. 
proc 16 took 24.502146 seconds. 
proc 3 took 24.513380 seconds. 
proc 1 took 24.541555 seconds. 
proc 8 took 24.539808 seconds. 
proc 13 took 24.540005 seconds. 
proc 12 took 24.556068 seconds. 
proc 10 took 24.528328 seconds. 
proc 19 took 24.585297 seconds. 
proc 6 took 24.611254 seconds. 

et les valeurs comprises entre les différents nombres de processeurs. Htop montre également une augmentation de la consommation de RAM (VIRT est ~ 100M pour 1 core, et ~ 300M pour 20). Bien que cela pourrait être lié à la taille du communicateur mpi? Enfin, il est certainement lié à la taille du problème (et donc pas un surcoût de communication causant un retard constant quelle que soit la taille de la boucle). En effet, diminuer l'imax pour dire 10 000 rend les walltimes similaires.

1 coeur:

proc 0 took 0.028439 seconds. 

20 cœurs:

proc 1 took 0.027880 seconds. 
proc 12 took 0.027880 seconds. 
proc 8 took 0.028024 seconds. 
proc 16 took 0.028135 seconds. 
proc 17 took 0.028094 seconds. 
proc 19 took 0.028098 seconds. 
proc 7 took 0.028265 seconds. 
proc 9 took 0.028051 seconds. 
proc 13 took 0.028259 seconds. 
proc 18 took 0.028274 seconds. 
proc 5 took 0.028087 seconds. 
proc 6 took 0.028032 seconds. 
proc 14 took 0.028385 seconds. 
proc 15 took 0.028429 seconds. 
proc 0 took 0.028379 seconds. 
proc 2 took 0.028367 seconds. 
proc 3 took 0.028291 seconds. 
proc 4 took 0.028419 seconds. 
proc 10 took 0.028419 seconds. 
proc 11 took 0.028404 seconds. 

Il a été essayé sur plusieurs machines avec des résultats similaires. Peut-être qu'il nous manque quelque chose de très simple.

Merci pour l'aide!

+0

Il se peut que la planification de plusieurs cœurs/threads prenne une quantité de temps mesurable. Vous avez besoin de beaucoup plus de travail dans chaque thread que le planificateur prendra de les planifier. De plus, si vous codez, la bande passante mémoire limitée limitera les performances. –

+0

Et encore une fois: C et C++ sont deux langages très différents. Sauf s'il y a une bonne raison, vous ne devriez pas taguer les deux! Au fait: qu'est-ce qui a fortran à faire avec ça? – muXXmit2X

+1

@ muXXmit2X J'ai mis plusieurs tags car cela a été testé dans différentes langues avec des résultats similaires. J'aurais dû le mentionner cependant. – AlexSzen

Répondre

2

processeur avec des fréquences turbo liées par la température.

Les processeurs modernes sont limités par la puissance de calcul thermique (TDP). Chaque fois que le processeur est froid, les cœurs simples peuvent accélérer jusqu'aux multiplicateurs de fréquence turbo. À chaud, ou plusieurs cœurs sans ralenti, les cœurs sont ralentis à la vitesse de base garantie. La différence entre les vitesses de base et de turbo est souvent autour de 400MHz. AVX ou FMA3 peuvent ralentir même en dessous de la vitesse de base.

+0

Je pense que la protection thermique est une source improbable du ralentissement signalé. Les processeurs semblent fonctionner pendant environ 25 ans. –

+0

un moyen de savoir est de désactiver le mode Turbo et exécuter à nouveau les tests –