首页 > 解决方案 > 如何使用 OpenMP 在其他 for 循环中并行化 for 循环

问题描述

我想获得并行这个循环的最佳性能:

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

最好的方法是什么?或者我应该在哪些情况下使用一种或另一种?

谢谢你。

标签: cparallel-processingopenmp

解决方案


单级并行化几乎总是最好的,即示例 1:第一个循环并行。

示例 2 实际上与示例 1 相同(第二个#pragma omp parallelfor 语句被忽略,因为嵌套并行化被禁用)。

示例 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
    }
}

推荐阅读