假设我有一个n元素和n_threads的向量。
我想使用#pragma omp parallel
使每个线程接收n / n_threads块大小,
最后一个取决于具体情况。
#include <stdio.h>
#include <omp.h>
int main()
{
int *v = malloc ( n * sizeof(int) );
#pragma omp parallel for (what should i put here?)
for(i = 0; i < n; ++i)
{
++v[i];
}
return 0;
}
Ex:n = 10003,n_threads = 4
答案 0 :(得分:3)
简而言之 - 你做不到。您所能做的就是在不指定块大小的情况下指定schedule(static)
子句,OpenMP运行时将以大致相同大小的块划分迭代计数。具体如何取决于实施。这就是OpenMP标准关于静态调度的内容:
当指定schedule(static,chunk_size)时,迭代被分成大小为chunk_size的块,并且以线程编号的顺序以循环方式将块分配给团队中的线程。
当没有指定chunk_size时,迭代空间被分成大小大致相等的块,并且最多一个块被分配给每个线程。请注意,在这种情况下,未指定块的大小。
对于n = 10003和n_threads = 4,您可以指定块大小为2500,迭代空间将被分成大小为2500,2500,2500,2500和3的块,它们将被分配给线程0,1,因此,线程0将获得2503次迭代,但它们在迭代空间中不会是连续的。如果您没有指定块大小,则由实现来决定给予额外迭代的线程。
答案 1 :(得分:0)
据我所知,OpenMP不能保证确切的块大小,但是自己计算它们并不难。这是一些示例代码:
#include <stdio.h>
#include <omp.h>
int main(void) {
int n = 10003;
int n_threads = 4;
int chunk_size = n / n_threads;
#pragma omp parallel num_threads(n_threads)
{
int id = omp_get_thread_num();
int b = id * chunk_size;
int e = id == n_threads - 1 ? n : b + chunk_size;
printf("thread %d: %d items\n", id, e - b);
for (int i = b; i < e; i++) {
// process item i
}
}
return 0;
}
示例输出:
thread 0: 2500 items
thread 1: 2500 items
thread 3: 2503 items
thread 2: 2500 items
当心:策略“每个线程获得n / n_threads个项目,最后一个又一个”对于您给出的数字是合适的,但是在其他情况下,这可能导致工作共享效率非常低下。例如,对于60个项目和16个线程,此公式将为所有线程提供3个项目-除了最后一个项目(该项目将获得15个项目)。如果处理每个项目花费的时间大致相同,则这意味着整个过程所花费的时间将比所需时间长四倍,并且大多数CPU内核大部分时间都处于空闲状态。我认为,只有在有充分的理由需要完全按照这种方式分配作品时,才应使用此公式。否则,OpenMP选择的块大小可能会更好。