【问题标题】:Matlab Array Ops OptimizationMatlab 数组运算优化
【发布时间】:2014-04-18 14:19:32
【问题描述】:

在一个 MATLAB 程序中,我多次(超过 300 万次)调用了一个函数,该函数将图像中的局部坐标转换为全局坐标,这只是一个简单的转换。我的整个代码运行需要 6 分钟,坐标转换函数需要 20% 的时间。

如何优化这段代码?

function LMP_glb = do(pnt_val,LMP,NP_glb)

    NP_co = ones(1,3)*round(pnt_val+1); 
    LMP_glb = [NP_glb(1:3) + LMP(1:3) - NP_co(1:3)]; %basic operations

end

注意:这个函数是从我的代码中的其他几个函数调用的(不是在一个无限的 for 循环中)。

谢谢。

【问题讨论】:

  • 我认为您需要针对调用函数进行优化,因为它看起来在这个函数中没有做太多。调用它一百万次并没有帮助。另外,我认为您可以直接将LMP_glb 设为LMP_glb = [NP_glb(1:3) + LMP(1:3) - round(pnt_val+1)];。如果pnt_val 是一个标量,MATLAB 会处理您在其上一行执行的大小调整。
  • 我同意。试试看能不能避免在几个地方调用这个函数。也许可以重复使用一次调用的结果而不是另一次调用。
  • 是的,您可以在一开始就预先计算所有坐标的结果(+在这种情况下使用矢量化),然后将这些结果作为参数传递给所有其他函数(会有只要您不修改子函数中的缓存结果,就没有复制开销)。

标签: arrays matlab optimization


【解决方案1】:

你可以把它简化一点:

function LMP_glb = do(pnt_val,LMP,NP_glb)

    LMP_glb = NP_glb(1:3) + LMP(1:3) - round(pnt_val+1);

end

因为 MATLAB 会为您处理将表达式的最后一部分从标量扩展为数组。

除此之外,我看不到太多优化它的方法,因为它没有做太多。如果你要内联它(即直接将表达式放在你的代码中,而不是作为函数调用它),你还可以节省函数调用开销所花费的时间——如果有 300 万次调用,那可能很贵。

@CitizenInsane 的建议也是一个很好的建议 - 如果可以一次为所有坐标预先计算此函数,然后稍后使用它们,则可以对操作进行矢量化以进一步加快速度。

最后,可以(如果您对小 C 语言感到满意)用 C 语言实现此函数,对其进行编译,然后将其作为 MEX 函数调用。这可能会也可能不会更快 - 您需要尝试一下。

【讨论】:

    【解决方案2】:

    我猜你的 do 函数是在某种 for 循环中调用的。如果您的 for 循环没有数据相互依赖,您可以简单地将其更改为 parfor,Matlab 将启动并行池以利用多核处理器,即并行计算。即使您的数据在 for 循环中交错,您也可以采取一些技巧来摆脱它(声明加法矩阵、数组以保存数据结构的另一个副本、以内存使用换取速度)。

    正如Sam所说,你可以用C/C++重写函数,用Matlab编译器编译,直接调用编译好的MEX函数。根据我的经验,C/C++ MEX 函数比 Matlab 内置的简单算术更快。

    Parfor 指南: http://www.mathworks.com/help/distcomp/getting-started-with-parfor.html

    墨西哥示例: http://www.mathworks.com/help/matlab/matlab_external/standalone-example.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 1970-01-01
      • 2021-03-03
      相关资源
      最近更新 更多