OpenMp - 每个线程的循环/数组边界

时间:2016-11-29 14:20:39

标签: c++ c openmp

是否存在ICV(内部控制变量)或类似的东西来查询OpenMP中循环的上限和下限?

在某些情况下,以下计算会给出上限和下限:

#pragma omp parallel for
for ( i = 0 ; i < n ; i++ ){
    int this_thread = omp_get_thread_num(), 
    num_threads = omp_get_num_threads();
    int lower_bound = (this_thread * n / num_threads);
    int upper_bound = ((this_thread+1) * n / num_threads) - 1;
...
}

对于n=100,我会为线程0, 25, 50 and 75获取24, 49, 74 and 99的正确下限和0, 1, 2, 3的上限。

如果我将n更改为99,则会给我不正确的界限。

GCC和Intel或C / C ++编译器的上限和下限计算是否不同?

2 个答案:

答案 0 :(得分:1)

OpenMP运行时库中没有任何函数可以为您提供此信息。此外,它将高度依赖于在循环上应用的调度。

默认情况下,如果没有明确的schedule指令,那么将应用的指令将依赖于编译器,并且不受OpenMP标准的指定。许多编译器将使用static调度,但情况并非如此,并且绝对无法保证。

现在,引用OpenMP标准来引用静态调度:

  

指定schedule(static, chunk_size)时,会划分迭代次数   分成大小为chunk_size的块,并将块分配给。{   团队中的线程以循环方式按顺序排列   线号。

     

如果未指定chunk_size,则迭代空间为   分成几乎大小相等的块,最多   每个线程分配一个块。块的大小是   在这种情况下没有说明。

正如您所看到的,即使在这种简单的情况下,如果没有给出块大小并且线程数没有均匀地划分迭代次数,则无法可靠地确定每个线程的下限和上限# 39;迭代。

如果你正确定义了块的大小,你应该能够可靠地计算每个线程的迭代范围。

现在,如果您的日程安排不是静态的,那么绝对无法推断哪个线程会获得什么样的迭代,因为这只会在运行时定义。

答案 1 :(得分:-1)

每个线程没有上限/下限。每个线程将在序列中选择下一个可用元素或下一个可用元素块。块大小是可配置的。

通常,内部使用原子增量,即InterlockedIncrement()。

顺便说一下,每个线程的下限/上限都是一个非常糟糕的主意。假设与其余元素相比,元素27的执行时间要长10倍。然后,必须处理此元素的不幸线程将比其他线程更晚完成。特定线程也可能被其他CPU活动停滞,每个线程拥有固定数量的元素将是非常低效的。