2016-11-12 49 views
2

我有一段代码,我想在多个线程中运行,但是当我增加线程数来运行时,我没有得到很多加速。在一个点之后,我得到的最差的线程越多,到比序列运行要糟糕得多的点。并行分配的工作组是否在其内部的部分中“增长”?

,所以我试图得到什么可能是问题的想法,我想知道如果打开MP允许我做什么,我想在第一个地方做。

该代码基本上是这样的。

int threads = omp_get_num_threads()/2; 

#pragma omp parallel for schedule(dynamic,1) num_threads(threads) 
for(i =0; i<len; i++) 
{ 
    #pragma omp sections 
    { 
    #pragma omp section 
    { 
    do_stuf(); 
    } 
    #pragma omp section 
    { 
    do_stuf2(); 
    } 
    } 
} 

想象一下,我有16个线程(在16核心机器上)。我正在寻找的是在for循环中创建一个8核心的工作组,并且当其中一个线程需要另一个for循环中的部分(因为有两个部分)时,我希望他们使用一个在我分配的工作组之外基本上是空闲的线程。

OpenMP的是否允许我做我想要什么,我只是在线程管理中的应用越来越开销?如果是这样,当“空闲”线程完成这项工作时,它会从分配给该工作组的工作组中分离出来,还是只会再次空闲?

还是我得到这一切都错了,部分都没有使用空闲线程?

谢谢

回答

0

你有两个简单的解决方案来解决这个问题,无论是使用嵌套并行:

  1. ,你提出的漂亮,很多,但简单地增加一个parallelsections指令,用num_threads(2)(这将使#pragma omp parallel sections num_threads(2),这与最初的omp_set_nested(1)使嵌套并行只想让你想要的东西一起。然而,这意味着,你将不得不处理初始化/终止嵌套线程池封闭循环的每次迭代。这可能会或可能不会增加一些开销,这取决于你的OpenMP实现的质量...
  2. 为了避免以往在环parallel指令,你可以先建立一个团队2个线程,对运行整个(鸟巢并行化)for循环,并根据它们的id仅运行do_stuf()函数中的一个。

这里是什么样子:

#include <stdio.h> 
#include <omp.h> 

void do_stuf1(int i, int tidl1) { 
    printf("1: idx %d tid level 1 %d, tid level 2 %d\n", 
      i, tidl1, omp_get_thread_num()); 
} 

void do_stuf2(int i, int tidl1) { 
    printf("2: idx %d tid level 1 %d, tid level 2 %d\n", 
      i, tidl1, omp_get_thread_num()); 
} 

int main() { 
    int nbth = omp_get_max_threads()/2; 
    omp_set_nested(1); 
    #pragma omp parallel num_threads(2) 
    { 
     int tidl1 = omp_get_thread_num(); 
     #pragma omp parallel for num_threads(nbth) 
     for (int i = 0; i < 10; i++) { 
      if (tidl1 == 0) { 
       do_stuf1(i, tidl1); 
      } 
      else if (tidl1 == 1){ 
       do_stuf2(i, tidl1); 
      } 
      else { 
       printf("**** that's not good!\n ****"); 
      } 
     } 
    } 
    return 0; 
} 

在我的机器,使用8个线程,这给了我这样的:

1: idx 6 tid level 1 0, tid level 2 2 
1: idx 7 tid level 1 0, tid level 2 2 
1: idx 8 tid level 1 0, tid level 2 3 
1: idx 9 tid level 1 0, tid level 2 3 
1: idx 0 tid level 1 0, tid level 2 0 
1: idx 1 tid level 1 0, tid level 2 0 
1: idx 2 tid level 1 0, tid level 2 0 
1: idx 3 tid level 1 0, tid level 2 1 
1: idx 4 tid level 1 0, tid level 2 1 
1: idx 5 tid level 1 0, tid level 2 1 
2: idx 0 tid level 1 1, tid level 2 0 
2: idx 1 tid level 1 1, tid level 2 0 
2: idx 2 tid level 1 1, tid level 2 0 
2: idx 3 tid level 1 1, tid level 2 1 
2: idx 4 tid level 1 1, tid level 2 1 
2: idx 5 tid level 1 1, tid level 2 1 
2: idx 6 tid level 1 1, tid level 2 2 
2: idx 7 tid level 1 1, tid level 2 2 
2: idx 8 tid level 1 1, tid level 2 3 
2: idx 9 tid level 1 1, tid level 2 3