Matlab mex文件与其直接C等效文件相比较慢

时间:2011-03-08 04:34:30

标签: c optimization matlab mex

我无法解释(并避免)Matlab mex程序与没有Matlab接口的相应C程序之间的速度差异。我一直在分析数值分析程序:

int main(){

Well_optimized_code();

}

使用gcc 4.4针对Matlab-Mex等效编译(指向使用gcc44,这不是Matlab当前支持的版本,但出于其他原因需要):

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

Well_optimized_code(); //literally the exact same code

}

我执行了时间:

$ time ./C_version

VS

>> tic; mex_version(); toc

时间上的差异是惊人的。从命令行运行的版本平均需要5.8秒。 Matlab中的版本在21秒内运行。对于上下文,mex文件替换了SimBiology工具箱中的算法,该算法大约需要26秒才能运行。

与Matlab的算法相比,C和mex版本都使用对openMP的调用线性扩展到27个线程,但为了进行性能分析,这些调用已被禁用并注释掉。

这两个版本以相同的方式编译,但必要的标志除了编译为mex文件外:-fPIC --shared -lmex -DMATLAB_MEX_FILE在mex编译/链接中应用。我删除了对mex文件的左右参数的所有引用。也就是说它不需要输入,也没有输出,只是用于分析。

伟大而光荣的谷歌已告诉我,与位置无关的代码不应成为经济放缓的源头,除此之外我不知所措。

任何帮助将不胜感激,

安德鲁

2 个答案:

答案 0 :(得分:14)

在Mathworks上与我的联系人发来一个月的电子邮件,玩弄我自己的代码,并在每个方向分析我的代码后,我得到了答案;然而,这可能是我对技术问题的最不满意的答案:

短版本是“升级到Matlab版本2011a(上周正式发布),此问题现已解决”。

较长的版本会考虑与版本2010b及更早版本中的mex网关相关的开销问题。我能够提取的最好的解释是,这个开销不会被评估一次,而是每次函数调用链接库中的另一个函数时我们都会支付一些费用。

虽然为什么会发生这种情况让我感到困惑,但至少与我所做的SHARK分析一致。当我分析和比较本机应用程序和mex应用程序之间的差异时,会出现重复出现的模式。我为应用程序编写的源代码中的函数花费的时间不会改变。在本机和mex实现之间进行比较时,在库函数中花费的时间会略微增加。用于构建此库的另一个库中的函数会大大增加差异。随着我们进行深入研究,时间差继续增加,直到我们通过BLAS实施达到目标。

一些使用频繁的BLAS功能是罪魁祸首。在本机应用程序中花费大约1%的计算时间的函数在mex函数中的时间为30%。

mex网关的实施似乎在2010b和2011a之间发生了变化。在我的Macbook上,本机应用程序大约需要6秒,而mex版本需要6.5秒。这是我可以处理的开销。

至于根本原因,我只能推测。 Matlab的根源在于解释性编码。由于mex函数是动态库,我猜测每个mex库都没有意识到它在运行时被链接的内容。由于Matlab建议用户很少使用mex,然后仅用于小型计算密集型块,我认为很少实现大型程序(例如ODE求解器)。像我这样的程序是受害最深的程序。

我已经分析了几个Matlab函数,我知道这些函数在C中实现然后使用mex编译(特别是在动力学模型上调用sbioaccelerate之后的sbiosimulate,SimBiology工具箱的一部分)并且似乎有一些显着的加速。因此,2011a更新似乎比通常的半年升级更为广泛。

对于遇到类似问题的其他程序员来说,祝你好运。感谢所有有用的建议让我开始朝着正确的方向前进。

- 安德鲁

答案 1 :(得分:3)

回想一下,Matlab将数组存储为列主要,将C / C ++存储为行主要。您的循环结构/算法是否可能以主要方式迭代,导致Matlab中的内存访问时间不佳,但C / C ++中的访问时间很短?