C++与 MEX 时序差异



我有一个mex(MATLAB版本的C++)函数,我想将其转换为C++。除了main()函数之外,它非常相似。但是其中一个子函数在使用 C++ 与 mex 编译时运行得相当慢。

我通过以下方式编译我的 mex 代码:

mex -v COMPFLAGS='$COMPFLAGS /std:c++11' COPTIMFLAGS="-O3" CFLAGS="$CFLAGS -fopenmp" rcp_adp.cpp -I/usr/include ini.c -I/usr/include cpp/INIReader.cpp -larmadillo -lopenblas -lgomp -lfftw3_omp -lfftw3 -lm -lpthread

我用它来C++编译:

g++ --verbose -std=c++11 rcp_main.cpp -I/usr/include ini.c -I/usr/include cpp/INIReader.cpp -O3 -larmadillo -llapack -lopenblas -lgomp -lfftw3_omp -lfftw3 -lm -fopenmp -lpthread

我无法发布子函数,但它使用犰狳函数和并行 for 循环进行信号处理。时差从0.5秒到25秒不等。

for 循环的调用方式如下:

#pragma omp parallel for num_threads(max_threads) /*do processing in parallel threads*/
for(int ii=0;ii<Nsp;ii++){
}

我不知道可能导致时间差异的原因。任何帮助将不胜感激。

编辑: 我只是想澄清一下,这是在两个实例中运行的确切代码。它是一个用C++编写的头文件。唯一的区别是,一个版本是使用 mex 命令在 MATLAB 中编译的,该命令与 g++ 链接,而另一个版本仅使用 g++。

所以我的工作理论是,当使用MEX/G ++/MATLAB进行编译时,MATLAB迫使编译器使用LAPACK和BLAS的MATLABs版本,而不是链接的openblas和lapack。我计划明天下午使用简化版本的代码进行测试,同时更新结果。

编辑: 抱歉,忘了提到我正在使用 Ubuntu 20.04。我还没有运行我的测试,但我已经进一步研究了 openblas。我看到有openblas-openmp,我如何链接到它而不是标准的openblas?

在 Windows 上,不使用CFLAGS环境变量。您不会将-fopenmp标志传递给编译器。我也不确定COPTIMFLAGS旗,你也可能没有通过-O3旗。

在 Windows 上,使用COMPFLAGS环境变量将标志传递给编译器。在 Linux 和 macOS 上,将CFLAGS用于 C 编译器,CXXFLAGS用于 C++ 编译器。这在文档中进行了描述。

如果您从 MATLAB 中运行mex,请执行

mex -v COMPFLAGS='$COMPFLAGS -std=c++11 -O3 -fopenmp' rcp_adp.cpp -I/usr/include ini.c -I/usr/include cpp/INIReader.cpp -larmadillo -lopenblas -lgomp -lfftw3_omp -lfftw3 -lm -lpthread

如果从 Windows 命令提示符运行mex,请使用"而不是'

所以解决了这个问题。看起来MEX/MATLAB是使用mkl blas库编译的,而g++是使用标准的openblas编译的。我安装 openblas-openmp

sudo apt install libopenblas-openmp-dev

然后我更新了链接指向的位置,以便它指向 openmp 版本(对 lapack 重复):

sudo update-alternatives --config libopenblas.so.0-x86_64-linux-gnu 

时间差异消失了。

最新更新