【问题标题】:OpenMP Parallel for with scheduling in COpenMP Parallel 用于 C 中的调度
【发布时间】:2014-03-12 11:03:16
【问题描述】:

我想运行一个并行的、计划的(例如静态/动态/引导式)for 循环,其中每个线程都有自己的一组变量,基于它们的线程 ID。我知道在并行 pragma 中声明的任何变量都是私有的,但我不想在 for 循环的每次迭代中重新声明变量。

在我的具体情况下,每当一组生成坐标位于圆的内部或外部时,我都会计算以近似 pi。 我正在使用 erand48(int[3] seed) 在每个线程中生成这些坐标,并且通过为每个线程提供一组不同的“seed”值,我将获得更多种类的数字用于近似值(也是此模拟的要求)。

  long long int global_result = 0;
  int tID = omp_get_thread_num();
  int[3] seed;
  seed[0] = (((tid*tid + 15) * 3)/7);
  seed[1] = ((((tid + tid) * 44)/3) + 2);
  seed[2] = tid;
  int this_result = 0;
#   pragma omp parallel for num_threads(thread_count) schedule(runtime)
      for(i = 0; i < chunksize; i++){
        x = erand48(seed);
        y = erand48(seed);
        ((x*x+y*y)>=1)?(this_result++):;    
      }
#   pragma omp critical{
      global_result+= this_result;
    }

这是尽我所能代表我正在尝试做的事情。我希望 'this_result'、'tid' 和 'seed' 的值具有私有范围。

【问题讨论】:

    标签: c openmp scheduling private parallel-for


    【解决方案1】:

    我知道在并行编译指示中声明的任何变量都是 私人的,但我不想在每个 for循环的迭代。

    将#pragma omp parallel for 分成两个独立的组件#pragma omp parallel 和#pragma omp for。然后,您可以在并行但在循环之外声明局部变量。 像这样的

    int global_result = 0; 
    #pragma omp parallel reduction(+:global_result)
    {
        int tid = omp_get_thread_num();
        int seed = (((tid*tid + 15) * 3)/7);
    // Typo, as commented below
    //  #   pragma omp parallel for schedule(runtime)
    //  What is intended!
    #   pragma omp for schedule(runtime)
          for(i = 0; i < chunksize; i++){
            float x = erand48(&seed);
            float y = erand48(&seed);
            if ((x*x+y*y)>=1)
                this_result++;    
          }
          global_result += this_result;
    }
    

    虽然有更好的方法来计算 pi :-)

    【讨论】:

    • 这是一个硬件任务。我也宁愿计算系列。不过,这确实解决了我的问题。
    • 内部杂注不应该有parallel
    • 你当然是对的!在网络“编辑器”中输入代码:-)
    • @JimCownie,没问题,我想自己编辑你的答案。我想我可以做到这一点,但我不确定即使对于如此微不足道的事情来说这是多么洁净......
    【解决方案2】:

    您可以像这样在#pragma 指令中使用“private”子句:

    #pragma omp parallel for private(this_result, tid, seed) num_threads(thread_count) schedule(runtime)
    

    如果我正确理解了您的问题,那应该可以。

    【讨论】:

    • 如何在 for 循环之外设置这些变量,以便它们根据它们的 thread_ID 具有不同的值?
    • 如果你在循环之外,在非并行部分,将只有一个线程(主线程)。因此,就我而言,您不能根据线程 ID 分配值。您可以做的一件事是将“种子”设置为 int[thread_count] 种子并为该向量的每个位置分配一个数字;然后,在循环内访问种子[omp_get_thread_num()],因此每个线程只能访问自己的数组位置(就像它是私有的一样)。
    猜你喜欢
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2011-05-14
    • 2012-05-09
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多