我想获得最佳性能来并行化此循环:
// EXAMPLE
for (;;) {
// DO SOMETHING
for(;;) {
// DO SOMETHING
}
}
我知道示例的三种并行化方式:
// EXAMPLE - FIRST LOOP PARALLEL
#pragma omp parallel for
for (;;) {
// DO SOMETHING
for(;;) {
// DO SOMETHING
}
}
// EXAMPLE - FIRST AND SECOND LOOP PARALLEL NO NESTED
omp_set_nested(0); // default option
#pragma omp parallel for
for (;;) {
// DO SOMETHING
#pragma omp parallel for
for(;;) {
// DO SOMETHING
}
}
// EXAMPLE - FIRST AND SECOND LOOP PARALLEL NESTED
omp_set_nested(1);
#pragma omp parallel for
for (;;) {
// DO SOMETHING
#pragma omp parallel for
for(;;) {
// DO SOMETHING
}
}
哪种方法最好?还是在哪种情况下应该使用其中一种?
谢谢。
答案 0 :(得分:2)
单个并行化级别几乎总是最好的,即示例1:第一个循环并行化。
示例2实际上与示例1相同(第二个#pragma omp parallel
语句被忽略,因为嵌套并行化被禁用了。)
示例3可能不是一个好主意。在循环1的每次迭代中都需要产生新线程的开销,这种情况只会使第一个循环(或仅第二个循环)并行化是不容易的。不能保证所有编译器都支持它(有些仍可能忽略嵌套部分)。
示例4是另一个选项,当出于任何原因(例如,内存使用)无法完成最外层循环的并行化,但是我们只希望生成一次线程,并在最外层的每次迭代中重新使用它们环。每次迭代都会产生一些同步开销,但比重复生成线程要花费的开销少得多。
// EXAMPLE - SECOND LOOP PARALLEL
#pragma omp parallel
for (;;) {
// DO SOMETHING EVERY THREAD SHOULD DO
// e.g. declare local variables, increment private counter...
#pragma omp single
{
// DO SOMETHING ONCE ONLY
// e.g. read data from a file, initialize a shared variable
}
#pragma omp for
for(;;) {
// DO SOMETHING
}
}