2012-03-24 11 views
1

Dies ist mein erstes Mal Posting, also werde ich für meine Anfänger Fehler appologise. Bitte entschuldigen Sie auch, dass nicht alle Variablennamen in Englisch sind. Mein Problem ist das Folgende: Ich habe diesen Code mit openMP sowohl in Visual Studio 2010 als auch in Eclipse für c/C++ mit der cygwin gcc Compiler Toolchain geschrieben. Im visuellen Bereich bekomme ich eine Beschleunigung, aber in der Finsternis verlangsame ich das Doppelte der seriellen Version. Kann mir bitte jemand bitte erklären, was ich falsch gemacht habe? Kurz gesagt simuliere ich einfach die Beschleunigung, wenn ich von einem Array von 3D-Vektoren in ein Doppel-Array kopiere, um über MPI zu senden.OpenMP Hilfe auf Code

#include <omp.h> 
#include <time.h> 
#include <stdio.h> 
#include <vector> 
const int NUMAR_FORME=10; 
    const int NUMAR_SECUNDE_SIMULATE=60; //number of buffers 
    const int dimensiuni_forme[10]={100,200,300,400,500,600,700,800,900,10000}; //size of each buffer 
    //-------- the buffers, cuurently only worker_buffer and buff is used 
    std::vector<std::vector<std::vector<double> > > worker_buffer; 
    std::vector<std::vector<double> > send_buffer,corect; 
    double **buff; 
    double **worker_buffer1; 
    long i,j,k,l; 
int flag=0; 
int numarator=0; //number of tests runed 
clock_t start; 
start=clock(); 
worker_buffer.resize(1); 
buff = new double* [2]; 
int de_scris=0; //this tells me in which buffer to store, nou I alternate buff[0], buff[1], buff[0], buff[1] 
worker_buffer[0].resize(NUMAR_SECUNDE_SIMULATE); 
for(i=0;i<NUMAR_SECUNDE_SIMULATE;i++) 
    worker_buffer[0][i].resize(dimensiuni_forme[9]); 



while(numarator<60) 
{ 

     if(numarator!=0) 
      delete [] buff[de_scris]; 

    if(numarator!=0) 
     de_scris=(de_scris+1)%2; 
    long limita; 
    limita=NUMAR_SECUNDE_SIMULATE*dimensiuni_forme[9]*3; //3-comes from the fact that I will have a 3D vector structure 
    buff[de_scris]= new double [limita]; 
    for(i=0;i<NUMAR_SECUNDE_SIMULATE;i++) 
    { for(j=0;j<dimensiuni_forme[9];j++) 
     { 
      worker_buffer[0][i][j]=(i*dimensiuni_forme[9]+j)*3; 
      buff[de_scris][(i*dimensiuni_forme[9]+j)*3]=worker_buffer[0][i][j]; 
      buff[de_scris][(i*dimensiuni_forme[9]+j)*3+1]=worker_buffer[0][i][j]+0.5; 
      buff[de_scris][(i*dimensiuni_forme[9]+j)*3+2]=worker_buffer[0][i][j]+0.75; 
     } 
    } 
    numarator++; 

} 

start=clock()-start; 
printf("TICKS TOTAL %ld \n",start); 
bool ad=true; 
long nr; 
for(i=0;i<NUMAR_SECUNDE_SIMULATE*dimensiuni_forme[9]*3;i++) 
{ 
    if(i%3==0) 
     nr=i; 
    if(i%3==0 && buff[de_scris][i]!=i) 
     ad=false; 
    else 
     if(i%3==1 &&buff[de_scris][i]!=(nr+0.5)) 
      ad=false; 
     else 
      if(i%3==2 && buff[de_scris][i]!=(nr+0.75)) 
       ad=false; 
} 
if(ad==false) 
    printf("not correct \n"); 
start=clock(); 

    numarator=0; 
//parallel version 
while(numarator<60) 
{ 


     if(numarator!=0) 
      delete [] buff[de_scris]; 

    long index, limita,id; 
    omp_set_num_threads(2); 

    if(numarator!=0) 
     de_scris=(de_scris+1)%2; 
    limita=NUMAR_SECUNDE_SIMULATE*dimensiuni_forme[9]*3; //3- 
    buff[de_scris]= new double [limita]; 
#pragma omp parallel shared(worker_buffer,limita,buff) private(index,id) 
    { 
     printf("intram cu %d threaduri \n", omp_get_num_threads()); 
     id=omp_get_thread_num(); 
     //index=id; 
     for(index=id;(index*3)<limita;index+=omp_get_num_threads()) 
     { 
      buff[de_scris][index*3]=worker_buffer[0][index/dimensiuni_forme[9]][index%dimensiuni_forme[9]]; //aici va veni send_buff[index].x 
      buff[de_scris][index*3+1]=buff[de_scris][index*3]+0.5; 
      buff[de_scris][index*3+2]=buff[de_scris][index*3]+0.75; 
     } 

    // index+=omp_get_num_threads(); 


    }//end parallel zone 
    numarator++; 
} 

start=clock()-start; 
printf("TICKS TOTAL %ld \n",start); 
ad=true; 
    //testing for correctness 
for(i=0;i<NUMAR_SECUNDE_SIMULATE*dimensiuni_forme[9]*3;i++) 
{ 
    if(i%3==0) 
     nr=i; 
    if(i%3==0 && buff[de_scris][i]!=i) 
     ad=false; 
    else 
     if(i%3==1 &&buff[de_scris][i]!=(nr+0.5)) 
      ad=false; 
     else 
      if(i%3==2 && buff[de_scris][i]!=(nr+0.75)) 
       ad=false; 
} 
if(ad==false) 
    printf("not correct \n"); 
return 0; 
} 
+0

Sie die Zeit nur mit der Uhr-Funktion in Ihrem Code messen Sie? Wenn ja, sollten Sie wissen, dass die Uhr die verwendete CPU-Zeit zurückgibt. Wenn Sie also zwei Sensoren verwenden, erhöht sich die von clock() zurückgegebene Zeit doppelt so schnell wie in Echtzeit. Ich bin nicht 100% sicher, wenn Visual C++ die Uhr() -Funktion auf die gleiche Weise implementiert, könnte der Grund sein, dass Sie unterschiedliche Zeiten messen. – Haatschii

+0

Ich habe versucht mit time() und clock_gettime() das Ergebnis war das gleiche – Ray

Antwort

1

zu urteilen, wie Sie diese für Schleife organisiert:

for(index=id;(index*3)<limita;index+=omp_get_num_threads()) 
    { 
     buff[de_scris][index*3]=worker_buffer[0][index/dimensiuni_forme[9]][index%dimensiuni_forme[9]]; //aici va veni send_buff[index].x 
     buff[de_scris][index*3+1]=buff[de_scris][index*3]+0.5; 
     buff[de_scris][index*3+2]=buff[de_scris][index*3]+0.75; 
    } 

und unter der Annahme, dass Sie 4 Threads haben, werden Ihre Themen verschachtelte Indexwerte erhalten:

thread 0: 0, 4, 8, 12,... 
thread 1: 1, 5, 9, 13,... 
thread 2: 2, 6, 10, 14,... 
thread 3: 3, 7, 11, 15,... 

welche verursacht werden kann, Cache-Ping-Pong-Effekte, da Werte, die von verschiedenen Threads geschrieben wurden, auf derselben Cache-Zeile landen können, was die Ausführung verlangsamt.

Versuchen Sie, eine einfache statische Partitionierung für Schleife zu verwenden, anstatt, um eine kontinuierliche Partitionen zu erhalten:

#pragma omp parallel for 
    for(index = 0; index < limita/3;index++) 
    { 
     buff[de_scris][index*3]=worker_buffer[0][index/dimensiuni_forme[9]][index%dimensiuni_forme[9]]; //aici va veni send_buff[index].x 
     buff[de_scris][index*3+1]=buff[de_scris][index*3]+0.5; 
     buff[de_scris][index*3+2]=buff[de_scris][index*3]+0.75; 
    } 
+0

Sie hatten Recht, vielen Dank, ich habe die Schleife, die Sie geschrieben haben, und es zeigte eine Beschleunigung. Seltsam, wie es im Visual eine Geschwindigkeit ohne die Direktive gezeigt hat. – Ray

+0

@Ray: Ich bin froh zu helfen. Vergiss nicht, die Antwort zu akzeptieren, wenn es dein Problem gelöst hat. – Tudor