OpenMP:在每个线程中都有一个完整的“for”循环

Posted

技术标签:

【中文标题】OpenMP:在每个线程中都有一个完整的“for”循环【英文标题】:OpenMP: having a complete 'for' loop into each thread 【发布时间】:2015-01-10 14:44:00 【问题描述】:

我有这个代码:

#pragma omp parallel

  #pragma omp single
  
    for (int i=0; i<given_number; ++i) myBuffer_1[i] = myObject_1->myFunction();
  

  #pragma omp single
  
    for (int i=0; i<given_number; ++i) myBuffer_2[i] = myObject_2->myFunction();
  


// and so on... up to 5 or 6 of myObject_x

// Then I sum up the buffers and do something with them
float result;
for (int i=0; i<given_number; ++i)
  result = myBuffer_1[i] + myBuffer_2[i];

// do something with result

如果我运行这段代码,我会得到预期的结果,但 CPU 使用率看起来相当高。相反,如果我在没有 OpenMP 的情况下正常运行它,我会得到相同的结果,但 CPU 使用率要低得多,尽管在单线程中运行。

我不想指定线程数,我希望程序根据 CPU 能力选择最大线程数,但我希望每个 for 循环完全在自己的线程中运行。我怎样才能做到这一点?

另外,我的期望是 myBuffer_1 的 for 循环运行一个线程,另一个 for 循环运行另一个线程,其余的在“主”线程中运行。这是正确的吗?

【问题讨论】:

【参考方案1】:

    #pragma omp single 末尾有一个隐式屏障,如果您希望两个 single 块同时运行,则需要使用 #pragma omp single nowait

    但是,根据您的要求,使用section 可能是一个更好的主意

    #pragma omp parallel
    
        #pragma omp sections 
        
            #pragma omp section 
            
                for (int i=0; i<given_number; ++i) myBuffer_1[i] = myObject_1->myFunction();  
            
            #pragma omp section
            
                for (int i=0; i<given_number; ++i) myBuffer_2[i] = myObject_2->myFunction();  
            
        
    
    
    

【讨论】:

我在尝试single之前尝试过sections,我也尝试过使用nowait,我总是得到相同的结果:我的程序运行17个线程,其中7个大约需要12,50即使处理“空闲”,也占总 CPU 的百分比。 CPU 是 i7(8 线程)。 发布一个最小的可运行测试用例,错误一定在其他地方。 我在帖子中编辑了示例代码,因为对缓冲区求和的for 循环必须在主线程中执行。顺便说一句,myObject_x 的函数 myFunction() 只是进行一系列非常复杂的计算并返回一个数字,我认为问题不存在,因为它们在没有 OpenMP 的情况下运行良好。只是我不知道如何让每个for循环在自己的线程中并行运行。 您如何衡量 CPU、每核或总数? OpenMP 尝试使用所有 CPU,对于 8 核 CPU,每个 CPU 将占用总 CPU 的 12.5%,这是您获得的数字。串行代码只使用 1 个核心,因此一个核心将使用总 CPU 的 12.5%,其余为 0%。 8 个线程中的 7 个每个占用 12,50%(正好是 100/8),所以我想每个线程都在其最大负载下工作,即使处理处于空闲状态(没有数据待处理),这对我来说很奇怪。

以上是关于OpenMP:在每个线程中都有一个完整的“for”循环的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ OpenMP 中为每个线程定义一个优先级队列

如何使用 OpenMP 将每个线程的输出返回到数组中?

用于嵌套 for 循环的 OpenMP?

循环C ++中的分段错误Openmp

确保混合 MPI / OpenMP 在不同的内核上运行每个 OpenMP 线程

OpenMP 中的线程任务调度