【问题标题】:MATLAB Mex function isn't faster than regular functionMATLAB Mex 函数并不比常规函数快
【发布时间】:2014-10-30 18:00:06
【问题描述】:

我知道情况并非总是如此,但 MEX 函数不应该提高代码效率,尤其是计算效率吗?

我已使用编码器工具包在 MATLAB 中对 expm 函数进行 MEX。由于该函数执行大量矩阵计算,因此我期待看到效率的显着提高。

但是,如下图所示,我没有看到时间上有太大的改善:

X 轴:expm 函数的另一个迭代

Y 轴:该函数的运行时间

蓝线:常规expm函数调用

红线: MEX'ed expm 函数调用

MEX 版与普通版如此相似是否有原因?有没有办法提高速度?我使用tictoc 收集有关运行时间的数据。

【问题讨论】:

  • 1) 您能否报告平均值/平均值,或绘制它们差异的直方图? 2)你用来测试速度的矩阵有多大?如果增加矩阵的大小会怎样?
  • 您会发现,在大多数情况下,算法是最重要的因素。在您的测试中,加载/使用 mex 的开销很可能等于 Matlab 中函数的开销,但如果没有 a) matlab 的工作副本和 b) 有关您的测试的更多信息,我无法判断。根据我的经验,Matlab 函数总体上都得到了很好的优化,并且某些 matlab 函数在没有一些手动优化的情况下无法转换为高效的 C/Cpp。
  • @George 平均而言,矩阵的大小从 12x12 到 18x18 不等,但这是平均水平。也有异常值。
  • 即使编译版本比未编译版本更有效(尽管我对此表示怀疑,请参阅 Mikael 的回答),但由于开销,我不希望它在如此小的情况下表现更好调用 MEX 函数。您是否尝试过使用更大的矩阵,比如数百或数千行/列?
  • @GBoggs:它还取决于您在 MATLAB Coder 中用于生成 C 代码的设置(您是否使用了固定大小的矩阵?项目设置中还有一个“速度”选项卡,您可以在其中启用某些优化)。您应该发布有关如何编译函数的更多详细信息,以及用于基准测试的代码...

标签: c++ performance matlab mex


【解决方案1】:

大多数 matlab 函数都是调用 FORTRAN 库代码的简单包装器,其中大部分来自 LAPACK / EISPACK / LINPACK。换句话说,一个内置的 matlab 函数调用已经在调用编译代码,而不是解释 matlab 代码(.m 源)。因此,MEX 无法提高这些函数调用的性能。

仅当您直接在 matlab 源代码中完成大量工作时,在 matlab 中编译代码才会带来好处。如果你的代码主要是调用一堆内置的 matlab 函数,尤其是矩阵函数(它们都是 LAPACK 函数),那么你不会看到太大的改进,只有当你有“手动”代码时,即,如果你完全在 matlab 代码中(在 .m 文件中)实现类似“expm”的东西,那么使用 MEX 编译时会快得多。如果您拥有大量自己的 matlab 代码,而不是仅对内置函数进行几次调用,您只会看到编译 matlab 代码的好处。

想一想,为什么 Mathworks 会发布带有内置函数的 Matlab,这些函数实现为解释的 matlab 代码?即使他们在 matlab 代码中实现了一些内置函数(这只是一小部分,因为大多数是 FORTRAN / C / C++),他们也会在发布之前编译这些函数,这样作为用户的你就可以得到最好的表现。

【讨论】:

  • edit expm?该函数不是本机函数。然而,这并不是一个特别复杂的函数——大部分繁重的工作都是通过调用mldivide来完成的。
【解决方案2】:

以下是对expm(A) 的调用在A = rand(500,500); 处发生故障的方式。

时间在矩阵乘法 (F = F*F;) 和对子函数 PadeApproximantOfDegree 的调用之间平均分配。 矩阵乘法是内置的,在 mkl.dll 中使用非常快速的 LAPACK 函数(MATLAB 的线性代数函数使用 Intel MKL)。

所有时间都花在PadeApproximantOfDegree上:

这不是循环。对内置矩阵数学函数的所有调用。如果有迭代,那么我希望 MATLAB 会慢一些,但这只是几行 1 call each 一直占用。只有父级 (F*F) 中的矩阵乘法被多次调用。

事实上,如果 MEX 版本更慢,如果 Coder 无法使用 MATLAB 可以访问的优化多线程库,我不会感到惊讶。显然 Coder 管理。

【讨论】:

  • 在 OP 的最后一个问题中,confirmed MATLAB 和 MATLAB Coder 都实现了相同的算法(Padé approximation with scaling and squareing)来计算矩阵指数(尽管最近版本中的一个小变化显然没有尚未移植到 MATLAB Coder)。事实上,当我上次尝试时,MATLAB Coder 已经生成了调用 BLAS/LAPACK 函数(dgemmdtstrm 等)的 C 代码,最终应该针对 MATLAB 附带的英特尔 MKL 库进行编译。
  • .. 所以我希望它们具有相似的性能,因为它们最终会从 MKL 调用相同的计算例程(同样使用 MATLAB 中的 JIT 编译,它应该加快 M 代码中的基本循环以获得接近原生性能)。如果 MEX 在 OP 的测试中稍微慢一些,我会简单地将其归因于调用 MEX 函数所涉及的开销。
  • 为了补充 chappjc 和 Amro 所说的内容,文档中还提到了一些用于加速代码的 strategiesbest practices。第一个链接描述了在运行时由优化的内置 MATLAB 函数控制时生成 MEX 通常不会显着提高性能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多