Openmp:所有线程由于一个线程中的延迟而停止

Openmp: all threads stop due to delay in one thread

本文关键字:线程 延迟 于一个 Openmp      更新时间:2023-10-16

我是OpenMP和并行编程的新手,并试图尝试它。我有一个包含 30 个元素的简单 for 循环,每个元素都由一个process()函数处理。但我故意延迟了一个元素(5th元素(。代码如下:

std::mutex mu;
void print_msg(const char* msg, size_t n)
{
mu.lock();
cout << msg << n << endl;
mu.unlock();
}
void process(size_t i)
{
print_msg("Processing ... ", i);
if (i == 5) // the 5th element is big, so takes time
for(int u=0; u<std::numeric_limits<int>::max(); u++);
}
int main(int argc, char *argv[])
{
#pragma omp parallel
{
#pragma omp for ordered schedule(dynamic, 3)
for(size_t i=0; i<30; i++)
{
process(i);
}
}
return 0;
}

我所期望的:

已分配5th元素(和其他 2 个元素(的线程将延迟,但其余元素将继续并行。

结果:

这是提到的延迟位置的结果...

Processing ... 1
Processing ... 0
Processing ... 4
Processing ... 2
Processing ... 5
Processing ... 3
Processing ... 6
Processing ... 7
Processing ... 8
[[ Here the execution paused for a couple of seconds and then
the below printed out all at once ]]
Processing ... 9
Processing ... 11
Processing ... 12
Processing ... 13
Processing ... 10
Processing ... 14
Processing ... 15
Processing ... 16
Processing ... 17
Processing ... 21
Processing ... 20
Processing ... 19
Processing ... 18
Processing ... 22
Processing ... 24
Processing ... 23
Processing ... 26
Processing ... 27
Processing ... 25
Processing ... 29
Processing ... 28

所以在我看来,不仅包含5th元素的线程停止了,而且所有其他线程也停止了。这是正常行为吗?

首先,你的线程不是"睡眠",而是在练习所谓的"忙碌等待",这对于长时间的延迟来说并不是很好(参见例如这里:"忙碌等待"与"睡眠"的权衡是什么?

但这里真正的问题似乎是使用

#pragma omp for ordered schedule(dynamic, 3)

这基本上意味着,线程将以 3 个为一组执行,下一组将等待前一组的结果(特定组按顺序执行(。对于dynamic,行为在某种程度上是随机的,对于static,我希望您会在组 0、1、2 和 3、4、5 之后看到暂停 - 这里的动态似乎第三组仍然执行,但下一组等到线程 5 完成。

尝试删除omp ordered行,然后应该允许并行执行所有线程,因此其他线程不会被线程 5 的执行阻塞。