【问题标题】:OpenMP for loopOpenMP for 循环
【发布时间】:2017-04-26 00:54:07
【问题描述】:

我是 Openmp 新手,我的任务是使用两种不同的可能性改进以下代码:

// Size = 400, CHUNKSIZE = 100 and there are 4 threads
#pragma omp parallel for schedule(static, CHUNK_SIZE)
  for(int i=0; i<SIZE; i++){
      for(int k=0; k<i; k++){
          A[i][k] = 42*foo 
       }
   }

起初我会将日程安排从静态更改为有指导的,因为第二个循环中的工作不平衡且稳步增长。 因此,首先块大小开始变大并减小以更好地处理迭代之间的负载不平衡。 ì 越大,第二个循环的工作量就越多。 在这一点上我不确定,如果动态而不是引导更好?

第二种可能性我不知道。

【问题讨论】:

    标签: c multithreading performance parallel-processing openmp


    【解决方案1】:

    因此,只需查看代码,您就可以告诉存在负载平衡问题。 IMO 你应该用schedule(static, 1) 测试你的代码,以保证你在线程之间有最小的负载不平衡(最多只有一次迭代)。然后与schedule(dynamic, 1) 进行比较,并验证使用dynamic 的开销(动态具有内部锁定机制)是否被线程间工作平衡所带来的收益所压倒。

    如果你仔细看,你可以看到内循环的工作以类似三角形的形状增长(N = SIZE)

     *k/i 0 1 2 3 4 5 ... N-1
     *  0 - x x x x x ... x 
     *  1 - - x x x x ... x 
     *  2 - - - x x x ... x
     *  3 - - - - x x ... x
     *  4 - - - - - x ... x
     *  5 - - - - - - ... x
     *  . - - - - - - ... x
     *  . - - - - - - ... x 
     *N-1 - - - - - - ... -    
     *  N - - - - - - ... - 
    

    因此,您可以进行自己的分配,以保证执行迭代 0 的线程也执行迭代 N-1,并且执行迭代 1 的线程也执行迭代 N-2,以及很快。以这种方式,您保证对于每个迭代线程将执行N - 1 内循环迭代。如下:

        int halfSIZE = SIZE >> 1;
    
        #pragma omp for schedule (static,1) nowait  
        for(int i = 0; i < halfSIZE; i++)
        {
            for(int k=0; k<i; k++)
               A[i][k] = 42*foo 
        } 
        
        #pragma omp for schedule (static,1)       
        for(int i = SIZE - 1; i >= halfSIZE; i--)
        {
              for(int k=0; k<i; k++)
                A[i][k] = 42*foo 
        }  
    

    【讨论】:

      【解决方案2】:

      假设您的意思是将一对循环包含在单个 omp 并行中,这可能是避免工作不平衡的合理方法。我仍然认为它不能保证太多。 您可以在线程数上放置一个外循环并计算 i 循环的迭代次数,该循环密切平衡每个线程设置的数组元素的数量。如果这对您的目标很重要,这可能是维护 NUMA 局部性的更有效方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-31
        • 2022-01-19
        • 1970-01-01
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多