是否有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活动也可以阻止特定线程,每个线程固定数量的元素效率很低。