c - 如何使用 OpenMP 在顺序循环中嵌套并行循环

标签 c multithreading loops parallel-processing openmp

我目前正在使用 OpenMP 进行矩阵计算。我的代码中有几个循环,而不是调用每个循环 #pragma omp parallel for[...] (创建所有线程并立即销毁它们)我想在开始时创建所有线程,并且在程序结束时删除它们以避免开销。 我想要这样的东西:

#pragma omp parallel
{
    #pragma omp for[...]
    for(...)

    #pragma omp for[...]
    for(...)
}

问题是我有一些部分只能由一个线程执行,但是在一个循环中,其中包含那些必须并行执行的循环...这就是它的样子:

//have to be execute by only one thread
int a=0,b=0,c=0;
for(a ; a<5 ; a++)
{

    //some stuff

    //loops which have to be parallelize
    #pragma omp parallel for private(b,c) schedule(static) collapse(2)
    for (b=0 ; b<8 ; b++);
        for(c=0 ; c<10 ; c++)
        {
            //some other stuff
        }

    //end of the parallel zone
    //stuff to be execute by only one thread

}

(在我的示例中,循环边界非常小。在我的程序中,迭代次数可以达到 20.000...) 我的第一个想法是做这样的事情:

//have to be execute by only one thread
#pragma omp parallel    //creating all the threads at the beginning
{
    #pragma omp master //or single
    {        
        int a=0,b=0,c=0;
        for(a ; a<5 ; a++)
        {

            //some stuff

            //loops which have to be parallelize
            #pragma omp for private(b,c) schedule(static) collapse(2)
            for (b=0 ; b<8 ; b++);
                for(c=0 ; c<10 ; c++)
                {
                    //some other stuff
                }

            //end of the parallel zone
            //stuff to be execute by only one thread

        }
    }
} //deleting all the threads

它没有编译,我从 gcc 得到这个错误:“工作共享区域可能没有紧密嵌套在工作共享、关键、有序、主任务或显式任务区域中”。

我知道它肯定来自“错误”的嵌套,但我不明白为什么它不起作用。我需要在平行区之前加一道屏障吗?我有点迷茫,不知道如何解决。

预先感谢您的帮助。 干杯。

最佳答案

大多数 OpenMP 运行时不会“创建所有线程并在之后立即销毁它们”。线程在第一个 OpenMP 部分的开头创建,并在程序终止时销毁(至少英特尔的 OpenMP 实现是这样做的)。使用一个大的并行区域而不是几个较小的并行区域没有性能优势。

Intel 的运行时(它是开源的并且可以在 here 中找到)有选项来控制线程用完工作时做什么。默认情况下,它们会旋转一段时间(以防程序立即开始一个新的并行部分),然后它们会让自己进入休眠状态。如果 do sleep,为下一个并行部分启动它们将需要更长的时间,但这取决于区域之间的时间,而不是语法。

关于c - 如何使用 OpenMP 在顺序循环中嵌套并行循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20110429/

相关文章:

c - 主机到网络双重?

c - 如何正确使用OpenMP?

java - While 循环和步骤

Java 字符串输入错误

c - 将文本文件输出到屏幕

c - 编译时出错 : "invalid operands to binary/(have ‘short int *’ and ‘int’ )"

c - 在 C 中创建递归数据结构的方法

java - 无法接收 UDP 数据报

c# - 带有自定义 TaskScheduler 的 Parallel.ForEach 以防止 OutOfMemoryException

python - 在没有 if 的循环中查找最大项