【发布时间】:2014-11-27 15:12:34
【问题描述】:
我正在阅读 Peter S. Pacheco 所著的并行编程简介一书。在 5.6.2 节中,它给出了一个关于减少 fork/join 开销的有趣讨论。 考虑奇偶转置排序算法:
for(phase=0; phase < n; phase++){
if(phase is even){
# pragma omp parallel for default(none) shared(n) private(i)
for(i=1; i<n; i+=2){//meat}
}
else{
# pragma omp parallel for default(none) shared(n) private(i)
for(i=1; i<n-1; i+=2){//meat}
}
}
作者认为上述代码的 fork/join 开销有些高。因为线程是在外循环的每次迭代中分叉和连接的。因此,他提出以下版本:
# pragma omp parallel default(none) shared(n) private(i, phase)
for(phase=0; phase < n; phase++){
if(phase is even){
# pragma omp for
for(i=1; i<n; i+=2){//meat}
}
else{
# pragma omp for
for(i=1; i<n-1; i+=2){//meat}
}
}
根据作者的说法,第二个版本在外循环开始之前分叉线程,并在每次迭代中重用线程,从而产生更好的性能。
但是,我怀疑第二个版本的正确性。在我的理解中,#pragma omp parallel 指令会启动一组线程,并让线程并行执行以下结构化块。在这种情况下,结构化块应该是整个外部 for 循环 for(phase=0 ...)。那么,在使用 4 个线程的情况下,不应该是整个外循环执行四次的情况吗?也就是说,如果n=10,那么将在 4 个线程上执行 40 次迭代。我的理解有什么问题? omp parallel(没有 for)如何与上面的以下 for 循环一起玩?
【问题讨论】:
标签: multithreading parallel-processing openmp