如何使用OpenMP

时间:2018-11-08 12:11:30

标签: c parallel-processing openmp

我想获得最佳性能来并行化此循环:

// 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
    }
}

哪种方法最好?还是在哪种情况下应该使用其中一种?

谢谢。

1 个答案:

答案 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
    }
}