OpenMP中是否有ICV(内部控制变量)或类似查询循环上下界的东西?
在某些情况下,以下计算会给出上限和下限:
#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 标准:
When
schedule(static, chunk_size)
is specified, iterations are divided into chunks of sizechunk_size
, and the chunks are assigned to the threads in the team in a round-robin fashion in the order of the thread number.When no
chunk_size
is specified, the iteration space is divided into chunks that are approximately equal in size, and at most one chunk is distributed to each thread. The size of the chunks is unspecified in this case.
如您所见,即使在这种简单的情况下,如果没有给出 block 大小并且线程数不能平均分配迭代次数,您就无法可靠地确定每个线程迭代的下限和上限。
但是,如果您正确定义 block 的大小,您应该能够可靠地计算每个线程的迭代边界。
现在,如果您的调度不是静态的,那么绝对没有办法推断哪个线程将获得哪个迭代,因为这只会在运行时定义。
关于c++ - OpenMp - 每个线程的循环/数组边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40868184/