2012-03-24 5 views
1

это мой первый пост, поэтому я буду приписывать свои новички. Также извините, что не все имена переменных написаны на английском языке. Моя проблема заключается в следующем: я написал этот код, используя openMP как в Visual Studio 2010, так и в eclipse для c/C++, используя компилятор cygwin gcc compiler. На визуальном уровне я получаю ускорение, но в eclipse я получаю медленное снижение объема серийной версии. Может кто-нибудь объяснить, что я сделал неправильно, пожалуйста? Короче говоря, я просто имитирую ускорение, когда я копирую из массива трехмерных векторов в двойной массив, чтобы отправить через MPI.Справка OpenMP по коду

#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

ли вы измерять время только с функцией синхронизации в коде? Если это так, вы должны знать, что часы возвращают время процессорного времени, то есть если вы используете 2 prossesors, время, возвращаемое clock(), будет увеличиваться в два раза быстрее, чем в реальном времени. Я не уверен на 100%, если visucal C++ реализует функцию clock() таким же образом, может быть причиной того, что вы измеряете разные времена. – Haatschii

+0

Я пробовал использовать time() и clock_gettime(), результат был тот же – Ray

ответ

1

Судя по тому, как вы организовали этот цикл:

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; 
    } 

и при условии, что у вас есть 4 темы, ваши темы будут чередоваться значения индекса:

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

, которые могут быть причиной кеш-пинг-понга, поскольку значения, написанные разными потоками, могут попадать в одну и ту же строку кэша, что замедляет выполнение.

Попробуйте использовать простой цикл со статическим секционирования вместо того, чтобы получить непрерывные разделы:

#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

Вы были очень благодарны, я использовал цикл, который вы написали, и он показал ускорение. Странно, как в визуальном режиме он показывал скорость без использования директивы for. – Ray

+0

@Ray: Рад помочь. Не забудьте принять ответ, если он решит вашу проблему. – Tudor

Смежные вопросы