我有2个循环,但我只想并行化内循环,因为预处理和后处理不能并行完成。所有foo()
函数调用一起占用99%的时间,因此当我使用pragma omp for
并行化for循环时,我希望获得线性加速,如下面的代码所示。但是,对于2个线程,我只获得1.87x的加速。
在下面的代码中,nodelist
包含foo()
使用的数据结构。这些结构是一些小向量和矩阵(foo()
是计算边界)。我正在使用动态调度,因为每个foo()
调用可能会有不同的执行时间。
while (changed){
//do some preprocessing
#pragma omp parallel for schedule(dynamic) num_threads(N_THREADS) private(j)
for (j = 0; j <= DIM - beta; j++) {
int tid = omp_get_thread_num();
res[j] = foo(mu, c, j, j+beta-1, nodelist[tid], out[j]);
}
//do some post-processing (which updates changed)
}
我还尝试在前处理和后处理中定义单个区域,并在while循环之前生成线程(如下所示),但它甚至不起作用。
#pragma omp parallel num_threads(N_THREADS)
{
while (changed){
#pragma omp single
{
//do some preprocessing
}
#pragma omp for schedule(dynamic) private(j)
for (j = 0; j <= DIM - beta; j++) {
int tid = omp_get_thread_num();
res[j] = foo(mu, c, j, j+beta-1, nodelist[tid], out[j]);
}
#pragma omp single
{
//do some post-processing (which updates changed)
}
}
}
使用Xcode的Instruments分析第一个代码时,负载似乎很平衡(1个线程为51.4%,另一个线程为47.6%)。对于4个线程,我得到了类似的结果,其中每个线程占总执行时间的23.4%-25%,但是加速(与使用的线程数相比)更差(在3.35x)。我认为问题可能是动态调度开销。我正在使用动态调度,因为在测试其他时,使用静态调度,OpenMP运行时系统无法有效地平衡工作,而在引导式调度中,它非常接近动态,但稍差。有人提出了一些关于我失去表现以及如何改进表现的提示吗?
由于