首页 文章

使用OpenMP并行化功能

提问于
浏览
1

我正在尝试并行运行代码,但我对与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的东西让它工作?谢谢!

2 回答

  • 1

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

    请注意,如果您并行执行文件IO,则可能看不到很多加速(如果你所做的只是文件IO,则几乎没有),除非至少有一些文件驻留在不同的物理硬盘上 .

  • 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)
        }
    }
    
    • 我将 vctfiles 标记为第一个私有,因为它们是只读的,我认为它们不应被修改,因此每个线程都会获得这些变量的副本 .

    • stackVct 在所有线程中被标记为共享,因为它们会对其进行修改 .

    • 最后只有一个线程将执行 doSingleTheadStuff 函数而不强制其他线程等待 .

相关问题