我是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
元素的线程停止了,而且所有其他线程也停止了。这是正常的行为吗?
答案 0 :(得分:2)
首先,你的线程并没有“睡觉”,而是在进行所谓的“忙碌等待”,这对于长时间延迟来说并不是那么好(例如见What are trade offs for “busy wait” vs “sleep”?)。
但这里真正的问题似乎是使用
#pragma omp for ordered schedule(dynamic, 3)
这基本上意味着线程将以3个为一组执行,下一个组将等待前一个的结果(特定组按顺序执行)。使用dynamic
行为有点随机,static
我希望你会在0,1,2和3,4,5之后看到暂停 - 这里有动态似乎第三group仍然让它执行但是下一组等到线程5完成。
尝试删除omp ordered
行,然后允许并行执行所有线程,因此执行线程5不会阻止其他线程。