我的程序结构与此类似:
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上做很多事情,但是我正在为一个良好的调度模式。
答案 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;
}
}