omp parallel vs. omp parallel for


105

两者有什么区别?

[一个]

#pragma omp parallel
{ 
    #pragma omp for
    for(int i = 1; i < 100; ++i)
    {
        ...
    }
}

[B]

#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
   ...
}

Answers:



66

这些是等效的。

#pragma omp parallel产生一组线程,同时#pragma omp for在产生的线程之间划分循环迭代。您可以使用fused #pragma omp parallel for指令同时执行这两项操作。


在我的代码中,我正在使用这种结构。但是,当我schedule(static, chunk)在for指令中使用子句时,出现问题。该代码运行良好,但是当我从MPI程序调用此代码时,它会陷入无限循环。在此循环的所有迭代中,循环计数器均为零。我在#pragma omp parallel指令中将循环计数器定义为私有。不知道为什么它仅在MPI调用代码时失败。如果有关系,我可以肯定每个MPI进程都在群集的不同处理器上运行。不知道时间表是否会导致问题。
罗希特·邦加

当我使用#pragma omp parallel for指令时,同样的东西也可以正常工作。应该有一些区别。
罗希特·邦加

1
更新:事实证明,只有在使用schedule子句时,我才观察到此问题,因此我想这并不取决于我将组合并行用于还是两个不同的指令。
罗希特·邦加

28

这是使用split parallelfor here的示例。简而言之,它可以用于for在多个线程中执行循环之前动态分配OpenMP线程专用数组。无法在中进行相同的初始化parallel for万一。

UPD:在问题示例中,单个编译指示和两个编译指示没有区别。但是在实践中,您可以使用分离的并行指令和for指令来实现更多的线程感知行为。一些代码例如:

#pragma omp parallel
{ 
    double *data = (double*)malloc(...); // this data is thread private

    #pragma omp for
    for(1...100) // first parallelized cycle
    {
    }

    #pragma omp single 
    {} // make some single thread processing

    #pragma omp for // second parallelized cycle
    for(1...100)
    {
    }

    #pragma omp single 
    {} // make some single thread processing again

    free(data); // free thread private data
}

9

尽管特定示例的两个版本是等效的,但正如其他答案中已经提到的那样,它们之间仍然存在一个小差异。第一个版本包含一个不必要的隐式屏障,在“ omp for”的末尾遇到。另一个隐式障碍可以在并行区域的末尾找到。至少从OpenMP角度来看,将“ nowait”添加到“ omp for”将使两个代码等效。我之所以这样说是因为OpenMP编译器在两种情况下可能会生成略有不同的代码。


7

在g ++ 4.7.0中使用for循环并使用时,我看到的运行时截然不同

std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;

for (int i = 0; i < 5000000; i++)
{
   double r1 = ((double)rand() / double(RAND_MAX)) * 5;
   double r2 = ((double)rand() / double(RAND_MAX)) * 5;
   x.push_back(r1);
   y.push_back(r2);
}

int sz = x.size();

#pragma omp parallel for

for (int i = 0; i< sz; i++)
   prod[i] = x[i] * y[i];

序列号(no openmp)在79毫秒内运行。“ parallel for”代码在29毫秒内运行。如果我省略for和使用#pragma omp parallel,则运行时将达到179ms,这比串行代码要慢。(机器的硬件并发性为8)

该代码链接到 libgomp


2
我认为这是因为omp parallel在单独的线程中执行循环而没有将其划分为多个线程,因此主线程正在等待第二个线程完成。时间花在同步上。
Antigluk 2012年

7
那是因为没有a #pragma omp for,就根本没有多线程共享循环。但是,这是不是OP的情况下,无论如何,有一个额外的重试#pragma omp for#pragm omp parallel和它应该运行类似(如果不相同)之类的#pragma omp parallel for版本。
Christian Rau

2
我认为这个答案是最好的答案,因为它表明它们不是“等效的”
失败的科学家

6

显然有很多答案,但是这个答案非常好(带有源代码)

#pragma omp for仅将循环的一部分委派给当前团队中的不同线程团队是执行程序的一组线程。在程序启动时,团队仅由一个 成员组成:运行程序的主线程

要创建新的线程组,您需要指定parallel关键字。可以在周围的上下文中指定:

#pragma omp parallel
{
   #pragma omp for
   for(int n = 0; n < 10; ++n)
   printf(" %d", n);
}

和:

什么是:平行的,对于一个团队

parallel,parallel for和for之间的区别如下:

团队是当前执行的线程组。在程序开始时,团队由一个线程组成。在下一个块/语句的持续时间内,并行构造将当前线程拆分为一个新的线程组,此后该团队又合并为一个。for将for循环的工作分配到当前团队的各个线程之间。

它不创建线程,仅在当前执行的团队的线程之间分配工作。parallel for是一次同时执行两个命令的缩写:parallel和for。Parallel创建一个新团队,并拆分该团队以处理循环的不同部分。如果您的程序从不包含并行构造,则线程数不超过一个;与非线程程序一样,启动程序并运行程序的主线程。

https://bisqwit.iki.fi/story/howto/openmp/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.