尽管并行编译,Mex 文件仍串行执行

Posted

技术标签:

【中文标题】尽管并行编译,Mex 文件仍串行执行【英文标题】:Mex file executing in series despite parallel compile 【发布时间】:2013-10-28 21:35:32 【问题描述】:

我正在使用 mex 文件测试基本的 openmp 并行化代码。问题是它似乎只运行一个线程,尽管我指示用 2 个线程运行它。代码如下:

#include "mex.h"
#include "omp.h"

#include <iostream>


void mexFunction(int nlhs, mxArray *plhs[],int nrhs,const mxArray *prhs[])

    using namespace std;
    #define x_out plhs[0]
    #define x_in prhs[0]

    double *x;
    double y;
    x_out=mxCreateDoubleMatrix(1,1,mxREAL);
    x=mxGetPr(x_out);
    y=mxGetScalar(x_in);

    x[0]=y;    
    omp_set_num_threads(2);
    int Nthreads=omp_get_num_threads();
    cout<<Nthreads<<"\n";
    #pragma omp parallel
    
        int ithread=omp_get_thread_num();

        #pragma omp for
                for (int i=0;i<10;i++)
                    cout<<"Hello! " <<i<<"\n";
    
    return;

我使用以下编译行 -

mex -v paralletestmex.cpp CC=g++ CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp"

并且在详细描述中显示了 fopenmp 标志,所以我猜它正在将其编译为并行。

我得到的输出是 -

1
Hello! 0
Hello! 1
Hello! 2
Hello! 3
Hello! 4
Hello! 5
Hello! 6
Hello! 7
Hello! 8
Hello! 9

显示由于某种原因,只创建了 1 个线程。这是针对我在更复杂代码上面临的问题的简单测试。当我在不使用 mex 的情况下将其作为纯 c++ 文件运行时,相同的代码似乎可以正常工作。

感谢任何帮助。谢谢! 悉达多

【问题讨论】:

您不会在任何地方打印ithread。如果迭代太少(展开循环)并且如果您只有一个 cpu/核心,openmp 可能会决定不并行化您的代码。 嗨,我实际上最初没有 for 循环,我只是打印 ithread,这显示我只有 0。此外,当我不在 mex 中执行此操作时,openmp 会并行化它。出于某种原因,我只是不为墨西哥做这件事。 【参考方案1】:

这是一个极其常见的错误:omp_get_num_threads() 返回当前团队中的线程数。在parallel 区域外调用时,它始终返回 1,因为根据定义,OpenMP 程序在并行区域外仅使用单个线程(主线程)执行。

omp_set_num_threads() 的补充调用是omp_get_max_threads()

另请注意,在编写模块和库函数时,调用omp_set_num_threads() 是一种非常糟糕的编程习惯。原因是它固定了所有并行区域的线程数,因此可能会影响其他代码。一个更好的方法是使用num_threads 子句:

#pragma omp parallel num_threads(2)

   // ...

【讨论】:

感谢您的回复和 cmets。所以我在并行区域内移动了 omp_get_num_threads() 和 cout 【参考方案2】:

好的,我做了一些研究,结果发现 mexopts.sh 文件中的 CXXOPTIMFLAGS 也需要更改。所以在我添加的编译行中:

CXXOPTIMFLAGS="\$CXXOPTIMFLAGS -fopenmp" 

这似乎可以完成这项工作。

感谢您的帮助!

【讨论】:

以上是关于尽管并行编译,Mex 文件仍串行执行的主要内容,如果未能解决你的问题,请参考以下文章

Mex 文件执行中的错误,Matlab 窗口

采用intel编译器并行编译执行杂化函数计算CP2K

尽管 deviceQuery 测试通过,CUDA 程序仍无法正确执行

尽管有一次编译指示,VS2012 仍抱怨“已定义”类

mex 文件:编译失败并带有“//”注释;但是在使用“/* */”时编译得很好[重复]

如何通过 Eclipse 编码和编译 Matlab mex 文件?