我有一个生成数据的大循环。例如,每次迭代需要 1 秒并产生一大块数据。我需要以正确的顺序将所有块写入文件。
如果我只是想并行化循环,我可以写这样的东西(高度简化):
FILE* f = fopen("output.txt", "w");
omp_lock_t lock;
omp_init_lock(&lock);
int nIterations = 1000000;
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
omp_set_lock(&lock);
fprintf(f, "%d\n", value);
omp_unset_lock(&lock);
}
}
#pragma omp barrier
fclose(f);
omp_destroy_lock(&lock);
这会将我的输出放入文件中,但不能保证条目的顺序。
我想同步执行,以便所有线程执行它们的任务,然后主线程写入文件,然后线程恢复。换句话说,我想要这样的东西:
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
int values[4];
for(int n=thread; n<nIterations; n+=4)
{
values[n] = do_computations(&a, &b, &c);
#pragma omp barrier
if(thread == 0)
{
for(int i=0; i<4; i++)
fprintf(f, "%d\n", values[i]);
}
#pragma omp barrier
}
}
#pragma omp barrier
除非出于某种莫名其妙的原因,OpenMP 规范禁止这样做。
或者我可以试试
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
#pragma omp ordered
{
fprintf(f, "%d\n", value);
}
}
}
#pragma omp barrier
fclose(f);
但这也行不通,因为“带有 for 构造的循环迭代......不能执行多个有序指令。”
我不想将代码重写为单个循环,也不想交换循环。
没有其他线程/同步工具,有没有一种干净的方法可以用 OpenMP 做到这一点?