我想使用 OpenMP 来并行化我的代码,但不确定我的循环如何保持其属性。
我知道内部循环产生了多少次结果,以及它有多大:
(根据宽度的均匀性,内环的行为不同,因此天花板和地板的划分)
const size_t
bytes_per_result = <something>,
totalloops = width/2 * iceildiv(width, 2);
所以我可以将每个结果写入文件内的已知位置。为此,我只需分配一个该大小的文件,然后将其倒回到开头:
FILE* f = fopen(<somefile>, "w");
fseek(f, totalloops * bytes_per_result - 1, SEEK_SET); //seek to before file end
fputc('\0', f); //write byte to allocate whole file
rewind(f);
然后我只是循环,并计算内部循环通过k
. 在最后一个循环之后,k == totalloops
.
result_t result;
size_t i, j, k;
for (i=0, k=0; i<width; i++) {
for (j=0; j<imin(i, width-i-1); j++, k++) {
result = do_calculation(i, j);
fseek(f, k * bytes_per_result, SEEK_SET);
fwrite_result(f, result);
}
}
现在我该如何并行化呢?并行化的东西当然是do_calculation
部分,而查找和写入必须一起声明#pragma omp critical
。但是我怎样才能k
表现得像我想要的那样?
OpenMP 只能解析简单的 for 循环,最后只有一个增量表达式,而不是两个,所以我不能k++
留在那里……</p>