gpt4 book ai didi

c++ - OpenMP 代码帮助

转载 作者:太空宇宙 更新时间:2023-11-04 12:11:01 26 4
gpt4 key购买 nike

这是我第一次发帖,所以我会为我的新手错误道歉。还请原谅并非所有变量名都是英文的。我的问题如下:我已经使用 cygwin gcc 编译器工具链在 Visual Studio 2010 和 eclipse for c/c++ 中使用 openMP 编写了这段代码。在 visual 中我得到了加速,但在 eclipse 中我得到的速度是串行版本的两倍。有人可以解释一下我做错了什么吗?简而言之,我只是模拟从 3D vector 数组复制到双数组以便通过 MPI 发送时的加速。

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

最佳答案

根据你如何组织这个 for 循环来判断:

    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,...

这可能会导致缓存乒乓效应,因为不同线程写入的值可能落在同一缓存行上,从而减慢执行速度。

尝试使用带有静态分区的简单 for 循环,以获得连续的分区:

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

关于c++ - OpenMP 代码帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9851267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com