【问题标题】:OpenMP for loopOpenMP for 循环
【发布时间】:2017-04-26 00:54:07
【问题描述】:
我是 Openmp 新手,我的任务是使用两种不同的可能性改进以下代码:
// Size = 400, CHUNKSIZE = 100 and there are 4 threads
#pragma omp parallel for schedule(static, CHUNK_SIZE)
for(int i=0; i<SIZE; i++){
for(int k=0; k<i; k++){
A[i][k] = 42*foo
}
}
起初我会将日程安排从静态更改为有指导的,因为第二个循环中的工作不平衡且稳步增长。
因此,首先块大小开始变大并减小以更好地处理迭代之间的负载不平衡。
ì 越大,第二个循环的工作量就越多。
在这一点上我不确定,如果动态而不是引导更好?
第二种可能性我不知道。
【问题讨论】:
标签:
c
multithreading
performance
parallel-processing
openmp
【解决方案1】:
因此,只需查看代码,您就可以告诉存在负载平衡问题。 IMO 你应该用schedule(static, 1) 测试你的代码,以保证你在线程之间有最小的负载不平衡(最多只有一次迭代)。然后与schedule(dynamic, 1) 进行比较,并验证使用dynamic 的开销(动态具有内部锁定机制)是否被线程间工作平衡所带来的收益所压倒。
如果你仔细看,你可以看到内循环的工作以类似三角形的形状增长(N = SIZE):
*k/i 0 1 2 3 4 5 ... N-1
* 0 - x x x x x ... x
* 1 - - x x x x ... x
* 2 - - - x x x ... x
* 3 - - - - x x ... x
* 4 - - - - - x ... x
* 5 - - - - - - ... x
* . - - - - - - ... x
* . - - - - - - ... x
*N-1 - - - - - - ... -
* N - - - - - - ... -
因此,您可以进行自己的分配,以保证执行迭代 0 的线程也执行迭代 N-1,并且执行迭代 1 的线程也执行迭代 N-2,以及很快。以这种方式,您保证对于每个迭代线程将执行N - 1 内循环迭代。如下:
int halfSIZE = SIZE >> 1;
#pragma omp for schedule (static,1) nowait
for(int i = 0; i < halfSIZE; i++)
{
for(int k=0; k<i; k++)
A[i][k] = 42*foo
}
#pragma omp for schedule (static,1)
for(int i = SIZE - 1; i >= halfSIZE; i--)
{
for(int k=0; k<i; k++)
A[i][k] = 42*foo
}
【解决方案2】:
假设您的意思是将一对循环包含在单个 omp 并行中,这可能是避免工作不平衡的合理方法。我仍然认为它不能保证太多。
您可以在线程数上放置一个外循环并计算 i 循环的迭代次数,该循环密切平衡每个线程设置的数组元素的数量。如果这对您的目标很重要,这可能是维护 NUMA 局部性的更有效方法。