Matlab:局部函数(子函数)是与主函数一起编译还是单独编译?

时间:2015-05-18 17:13:29

标签: performance matlab optimization compiler-optimization

我听说MATLAB有一个自动的需要的函数编译,如果你多次调用一个函数,可能会产生大量的函数调用开销,如下面的代码所示:

function output = BigFunction( args )
    for i = 1:10000000
        SmallFunction( args );
    end
end

如果我将函数SmallFunction()作为本地函数放在与BigFunction()相同的文件中,是否更快调用它?或者除了将代码从SmallFunction()粘贴到BigFunction()以优化性能之外,还有什么好的解决方案吗?

编辑:假设函数调用开销是因为需要编译,可能是错误的假设。问题是如何在不使代码看起来很糟糕的情况下减少开销。

2 个答案:

答案 0 :(得分:0)

Matlab将它读取的函数哈希到内存中。如果函数作为独立函数存在于其自己的文件中,则只编译一次。如果您将BigFunction放在BigFunction.mSmallFunction SmallFunction.m中,那么您应该接受将m脚本编译一次的优化优势。

答案 1 :(得分:0)

我的第一个问题的答案是本地函数与另一个文件中的函数执行相同的操作。

第二个问题的一个想法是,如果可能的话,使SmallFunction()成为内联函数,它具有较少的函数调用开销。我在MathWorks forum中找到了更多关于函数调用性能的信息,并在下面粘贴了问题和答案:

问题:

  

我有7种不同类型的函数调用:

     
      
  1. 内联函数。该函数的主体是向下写入的目录(内联)。

  2.   
  3. 函数在单独的MATLAB文件中定义。参数由调用函数(文件传递)传递。

  4.   
  5. 函数在单独的MATLAB文件中定义。通过引用全局变量来提供参数;只有索引由调用函数(文件全局)提供。

  6.   
  7. 嵌套函数。参数由封闭函数(nest-pass)传递。

  8.   
  9. 嵌套函数。参数是与封闭函数共享的参数;只有索引由封闭函数(nest-share)提供。

  10.   
  11. 子功能。参数由调用函数(子传递)传递。

  12.   
  13. 子功能。通过引用全局变量来提供参数;只有索引由调用函数(子全局)提供。

  14.         

    我想知道哪个函数调用提供了比其他函数调用更好的性能。

MathWorks支持团队的答案粘贴在这里:

  

从最快到最慢的每个函数调用的性能顺序倾向于如下:

     

inline> file-pass = nest-pass = sub-pass> nest-share> sub-global>文件全局

     

(A> B表示A比B快,A = B表示A和B一样快)

     

首先,内联是最快的,因为它不会产生与函数调用相关的开销。

     

其次,当参数传递给被调用函数时,调用函数以这样的方式设置参数,即被调用函数知道在哪里检索它们。与函数调用相关的这种设置通常会导致性能开销,因此文件传递,嵌套传递和子传递比内联慢。

     

第三,如果工作空间与嵌套函数共享,并且嵌套函数的参数是在工作空间内共享的参数,而不是按值传递,则禁止执行该函数调用。如果MATLAB在共享工作空间中看到共享变量,它会在工作空间中搜索变量。另一方面,如果参数由调用函数传递,则MATLAB不必搜索它们。此搜索所花费的时间解释了类型nest-share比file-pass,nest-pass和sub-pass慢。

     

最后,当函数调用涉及全局变量时,性能甚至会被抑制。这是因为要查找全局变量,MATLAB必须将其搜索空间扩展到当前工作空间的外部。此外,涉及全局变量的函数调用看起来比其他变量慢得多的原因是MATLAB Accelerator不优化这样的函数调用。使用以下命令关闭MATLAB加速器时,

     

功能加速关闭   内联和文件全局之间的性能差异变得不那么重要了。

     

请注意,这些行为在很大程度上取决于各种因素,例如操作系统,CPU架构,MATLAB Interpreter以及MATLAB代码正在做什么。