在while循环内与openMP并行进行for循环?

时间:2019-01-07 18:23:42

标签: c++ openmp

我的程序结构与此类似:

ssize_t remain = nsamp;
while (!nsamp || remain > 0) { 
    #pragma omp parallel for num_threads(nthread)  
    for (ssize_t ii=0; ii < nthread; ii++) {
        <generate noise>       
    } 

    // write noise
    out.write(data, nthread*PERITER);
    remain -= nthread*PERITER;
 }

问题是,当我对它的输出进行基准测试时,如果我使用例如:两个线程运行,有时与一个线程花费的时间大约相同,有时我得到2倍的加速,那感觉就像是某种我遇到的同步竞赛条件,有时候我碰到了它,事情进展得很顺利,有时(通常)不是。

有人知道这可能是什么原因吗,以及使外部while循环内部的部分并行化的正确方法是什么?

编辑:使用strace,我看到对sched_yield()的调用的 lot ,这可能看起来像我在CPU上做很多事情,但是我正在为一个良好的调度模式。

2 个答案:

答案 0 :(得分:0)

每次进入while循环时,您将创建一堆新的线程。并行循环后,线程将被销毁。由于while循环的性质,这可能会不规则地发生(取决于条件)。 因此,如果您的循环仅执行几次,那么线程创建过程可能会超过实际的工作量,因此,即使不是更少,您也可以获得最多的顺序性能。但是,也许并行系统(OpenMP)可以检测是否多次进入循环以保持线程活动。

虽然没有保证。

答案 1 :(得分:0)

我建议这样的事情。 对于nsamp == 0,您将需要一些更合理的处理。有关使用OpenMP正确处理信号的信息,请参阅this answer

ssize_t remain = nsamp;
#pragma omp parallel num_threads(nthread) shared(out, remain, data)
while (remain > 0) { 
    #pragma omp for
    for (ssize_t ii=0; ii < nthread; ii++) {
        /* generate noise */
    }
    #pragma omp single
    {
        // write noise
        out.write(data, nthread*PERITER);
        remain -= nthread*PERITER;
    }
}