OpenMP:让线程按顺序执行for循环
OpenMP: Having threads execute a for loop in order
我想运行像下面这样的东西:
for (int index = 0; index < num; index++)
我想要 运行 具有四个线程的 for 循环,线程按以下顺序执行:0、1、2、3、4、5、6、7、8 等。 ..
也就是说,对于要在 index =n,(n+1),(n+2),(n+3)
上工作的线程(以任何特定顺序但始终采用这种模式),我希望 index = 0,1,2,...(n-1)
的迭代已经完成。
有没有办法做到这一点? Ordered 在这里并不真正起作用,因为将正文设为有序部分基本上会为我消除所有并行性,并且调度似乎不起作用,因为我不希望线程在线程 k->k+[=17 上工作=].
感谢您的帮助!
我不确定我是否正确理解了您的请求。如果我试着总结一下我是如何解释它的,那将是这样的:“我想要 4 个线程共享一个循环的迭代,在循环的 4 个连续迭代中最多总是有 4 个线程 运行”。
如果这就是你想要的,那么这样的事情怎么样:
int nths = 4;
#pragma omp parallel num_thread( nths )
for( int index_outer = 0; index_outer < num; index_outer += nths ) {
int end = min( index_outer + nths, num );
#pragma omp for
for( int index = index_outer; index < end; index++ ) {
// the loop body just as before
} // there's a thread synchronization here
}
你可以做到这一点,不是并行 for 循环,而是一个并行区域,它在内部管理自己的循环,加上一个屏障,以确保所有 运行 线程在被执行之前都在其中命中相同的点能够继续。示例:
#include <stdatomic.h>
#include <stdio.h>
#include <omp.h>
int main()
{
atomic_int chunk = 0;
int num = 12;
int nthreads = 4;
omp_set_num_threads(nthreads);
#pragma omp parallel shared(chunk, num, nthreads)
{
for (int index; (index = atomic_fetch_add(&chunk, 1)) < num; ) {
printf("In index %d\n", index);
fflush(stdout);
#pragma omp barrier
// For illustrative purposes only; not needed in real code
#pragma omp single
{
puts("After barrier");
fflush(stdout);
}
}
}
puts("Done");
return 0;
}
一个可能的输出:
$ gcc -std=c11 -O -fopenmp -Wall -Wextra demo.c
$ ./a.out
In index 2
In index 3
In index 1
In index 0
After barrier
In index 4
In index 6
In index 5
In index 7
After barrier
In index 10
In index 9
In index 8
In index 11
After barrier
Done
我想运行像下面这样的东西:
for (int index = 0; index < num; index++)
我想要 运行 具有四个线程的 for 循环,线程按以下顺序执行:0、1、2、3、4、5、6、7、8 等。 ..
也就是说,对于要在 index =n,(n+1),(n+2),(n+3)
上工作的线程(以任何特定顺序但始终采用这种模式),我希望 index = 0,1,2,...(n-1)
的迭代已经完成。
有没有办法做到这一点? Ordered 在这里并不真正起作用,因为将正文设为有序部分基本上会为我消除所有并行性,并且调度似乎不起作用,因为我不希望线程在线程 k->k+[=17 上工作=].
感谢您的帮助!
我不确定我是否正确理解了您的请求。如果我试着总结一下我是如何解释它的,那将是这样的:“我想要 4 个线程共享一个循环的迭代,在循环的 4 个连续迭代中最多总是有 4 个线程 运行”。
如果这就是你想要的,那么这样的事情怎么样:
int nths = 4;
#pragma omp parallel num_thread( nths )
for( int index_outer = 0; index_outer < num; index_outer += nths ) {
int end = min( index_outer + nths, num );
#pragma omp for
for( int index = index_outer; index < end; index++ ) {
// the loop body just as before
} // there's a thread synchronization here
}
你可以做到这一点,不是并行 for 循环,而是一个并行区域,它在内部管理自己的循环,加上一个屏障,以确保所有 运行 线程在被执行之前都在其中命中相同的点能够继续。示例:
#include <stdatomic.h>
#include <stdio.h>
#include <omp.h>
int main()
{
atomic_int chunk = 0;
int num = 12;
int nthreads = 4;
omp_set_num_threads(nthreads);
#pragma omp parallel shared(chunk, num, nthreads)
{
for (int index; (index = atomic_fetch_add(&chunk, 1)) < num; ) {
printf("In index %d\n", index);
fflush(stdout);
#pragma omp barrier
// For illustrative purposes only; not needed in real code
#pragma omp single
{
puts("After barrier");
fflush(stdout);
}
}
}
puts("Done");
return 0;
}
一个可能的输出:
$ gcc -std=c11 -O -fopenmp -Wall -Wextra demo.c
$ ./a.out
In index 2
In index 3
In index 1
In index 0
After barrier
In index 4
In index 6
In index 5
In index 7
After barrier
In index 10
In index 9
In index 8
In index 11
After barrier
Done