我遇到OpenMP任务问题。我正在尝试使用omp任务创建“for”循环的并行版本。但是,这个版本的执行时间比基本版本长2倍,我使用omp,我不知道是什么原因。看看代码风箱:
omp for version:
t.start();
#pragma omp parallel num_threads(threadsNumber)
{
for(int ts=0; ts<1000; ++ts)
{
#pragma omp for
for(int i=0; i<size; ++i)
{
array_31[i] = array_11[i] * array_21[i];
}
}
}
t.stop();
cout << "Time of omp for: " << t.time() << endl;
omp任务版本:
t.start();
#pragma omp parallel num_threads(threadsNumber)
{
#pragma omp master
{
for(int ts=0; ts<1000; ++ts)
{
for(int th=0; th<threadsNumber; ++th)
{
#pragma omp task
{
for(int i=th*blockSize; i<th*blockSize+blockSize; ++i)
{
array_32[i] = array_12[i] * array_22[i];
}
}
}
#pragma omp taskwait
}
}
}
t.stop();
cout << "Time of omp task: " << t.time() << endl;
在任务版本中,我以与omp相同的方式划分循环。每个任务都必须执行相同数量的迭代。任务总量等于线程总数。
表现结果:
Time of omp for: 4.54871
Time of omp task: 8.43251
有什么问题?是否有可能在两个版本中获得类似的性能?附加代码很简单,因为我只想说明我试图解决的问题。我不希望两个版本都给我相同的性能,但我想减少差异。
感谢您的回复。 最好的问候。
答案 0 :(得分:0)
我认为这里的问题是开销。当您将循环声明为并行时,它会指定所有线程一次执行for循环的所有部分。当您启动任务时,每次启动任务时都必须完成整个设置过程。为什么不这样做呢。
#pragma omp parallel num_threads(threadsNumber)
{
#pragma omp master
{
for(int ts=0; ts<1000; ++ts)
{
#pragma omp for
for(int th=0; th<threadsNumber; ++th)
{
for(int i=th*blockSize; i<th*blockSize+blockSize; ++i)
{
array_32[i] = array_12[i] * array_22[i];
}
}
}
}
}
答案 1 :(得分:0)
我要说你在这里尝试的问题与数据亲和性有关:当你使用#pragma omp for
时,跨线程迭代的分布对于{{1的所有值总是相同的而对于任务,您无法指定任务与线程的绑定。
一旦这样说,我已经在我的机器中执行了三个1M元素阵列的程序,两个版本之间的结果更接近:
(我使用ts
)