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的正确lower_bound和 24, 49, 74 and 99的上围线0, 1, 2, 3

如果我将 n更改为 99,它将给我不正确的范围。

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

openMP运行时库中没有功能,可以为您提供此信息。此外,这将在很大程度上取决于循环上应用的调度。

默认情况下,在没有明确的schedule指令的情况下,将应用的指令依赖于编译器,并由OpenMP标准指定。许多编译器将使用static计划,但并非总是如此,绝对不能保证。

现在,仅引用有关静态调度的OpenMP标准:

当指定schedule(static, chunk_size)时,迭代会划分 分成大小chunk_size的块,将块分配给 以圆形旋转方式在团队中的线程按顺序排列 线程号。

当未指定chunk_size时,迭代空间为 分为大小大致相等的块,至多 一个块分布到每个线程。块的大小是 在这种情况下未指定。

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

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

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

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

通常,原子增量将在内部使用,即互锁()。

顺便说一下,每个线程具有下限/上限是一个非常糟糕的主意。假设与其余的元素27相比,执行时间更长10倍。那么必须处理此元素的不幸线程将比其他线程晚得多。其他CPU活动也可以阻止特定线程,每个线程固定数量的元素效率很低。

最新更新