2

我正在尝试并行运行代码,但我对与 openmp 相关的私有/共享等内容感到困惑。我正在使用 c++(msvc12 或 gcc)和 openmp。

代码迭代循环,该循环由一个应该并行运行的块组成,然后是一个应该在所有并行工作完成后运行的块。处理并行内容的顺序无关紧要。代码如下所示:

// some X, M, N, Y, Z are some constant values
const int processes = 4;
std::vector<double> vct(X);
std::vector<std::vector<double> > stackVct(processes, std::vector<double>(Y));
std::vector<std::vector<std::string> > files(processes, M)
for(int i=0; i < N; ++i)
{
  // parallel stuff
  for(int process = 0; process < processes; ++process)
  {
    std::vector<double> &otherVct = stackVct[process];
    const std::vector<std::string> &my_files = files[process];

    for(int file = 0; file < my_files.size(); ++file)
    { 
      // vct is read-only here, the value is not modified
      doSomeOtherStuff(otherVct, vct);

      // my_files[file] is read-only
      std::vector<double> thirdVct(Y);
      doSomeOtherStuff(my_files[file], thirdVct(Y));

      // thirdVct and vct are read-only
      doSomeOtherStuff2(thirdVct, otherVct, vct);
    }
  }
  // when all the parallel stuff is done, do this job
  // single thread stuff
  // stackVct is read-only, vct is modified
  doSingleTheadStuff(vct, stackVct)
}

如果性能更好,可以将“doSingleThreadSuff(...)”移到并行循环中,但需要单线程处理。最内层循环中的函数顺序不能更改。

我应该如何声明#pragma omp 的东西以使其正常工作?谢谢!

4

2 回答 2

1

并行运行 for 循环就#pragma omp parallel for在循环语句的上方,for并且在 for 循环之外声明的任何变量都由所有线程共享,并且在 for 循环内声明的任何变量都是每个线程私有的。

请注意,如果您正在并行执行文件 IO,您可能看不到太多加速(如果您所做的只是文件 IO,则几乎没有),除非至少有一些文件位于不同的物理硬盘驱动器上。

于 2013-09-14T19:17:53.127 回答
1

也许是这样的(请注意,这只是一个草图,我没有验证它,但你可以理解):

// some X, M, N, Y, Z are some constant values
const int processes = 4;
std::vector<double> vct(X);
std::vector<std::vector<double> > stackVct(processes, std::vector<double>(Y));
std::vector<std::vector<std::string> > files(processes, M)
for(int i=0; i < N; ++i)
{
    // parallel stuff
    #pragma omp parallel firstprivate(vct, files) shared(stackVct)
    {
        #pragma omp for
        for(int process = 0; process < processes; ++process)
        {
            std::vector<double> &otherVct = stackVct[process];
            const std::vector<std::string> &my_files = files[process];

            for(int file = 0; file < my_files.size(); ++file)
            {
                // vct is read-only here, the value is not modified
                doSomeOtherStuff(otherVct, vct);

                // my_files[file] is read-only
                std::vector<double> thirdVct(Y);
                doSomeOtherStuff(my_files[file], thirdVct(Y));

                // thirdVct and vct are read-only
                doSomeOtherStuff2(thirdVct, otherVct, vct);
            }
        }
        // when all the parallel stuff is done, do this job
        // single thread stuff
        // stackVct is read-only, vct is modified
        #pragma omp single nowait
        doSingleTheadStuff(vct, stackVct)
    }
}
  • vct我将and标记files为第一个私有,因为它们是只读的,并且我认为它们不应该被修改,所以每个线程都会为自己获取这些变量的副本。
  • stackVct标记为在所有线程之间共享,因为它们对其进行了修改。
  • 最后只有一个线程会执行该doSingleTheadStuff函数,而不会强制其他线程等待。
于 2013-09-14T20:45:43.363 回答