MATLAB Magical Mystery计时行为

时间:2009-08-21 18:08:00

标签: matlab

我正在从我写的函数中经历一些非常奇怪的计时行为。如果我将我的函数包装在另一个空容器函数中,它将获得3倍的加速。

  

>>抽动; FOO(参数); TOC

时间过去了:~140秒

  

>>抽动;巴(参数); TOC

时间过去了:~35秒

这是踢球者 - bar()的定义:

  

定义bar(args)

     
    

FOO(参数)

  
     

是否存在某种针对嵌套函数调用在MATLAB中触发的优化?我应该为我写的每个函数添加一个虚函数吗?

4 个答案:

答案 0 :(得分:3)

据我所知,JIT加速器不能在命令行表达式上运行。因此,当你运行“tic; foo(args); toc”时,foo的代码完全在MATLAB解释器中运行。但是,当你运行“tic; bar(args); toc”时,bar会在解释器中进行计算,而JIT加速器会将对foo()的调用编译为本机代码。

我真的在细节上挥手,但这就是它的要点。 MATLAB的JIT功能的细节很难得到;我发现的大部分内容都发生在The MathWorks的Loren博客上。我可以找到关于命令行只有解释器的最近权威声明在这里: http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/#comment-207

答案 1 :(得分:1)

你是否第二次尝试foo而没有清除变量?我无法重现这种性能提升如果我重复运行它。另外,它确实看起来更快,但这只是因为如果你运行它们,MATLAB会预先编译这些函数。

function barfoo    

    for i = 1:Inf
    end    

end

而且,

function foobar        
    barfoo();
end

答案 2 :(得分:1)

我不知道您是否尝试多次运行代码,但我注意到的一个可能的解释是,新更新文件的第一次运行通常比后续运行慢(我假设由于编译) 。我猜你可能会看到以下第三行的不同时间(在修改foo后调用):

tic; foo(args); toc;  % First call of foo
tic; bar(args); toc;  % Second call of foo inside bar
tic; foo(args); toc;  % Third call of foo

答案 3 :(得分:1)

这是令人惊讶的行为。中间函数调用不应该加速这样的事情。

尝试对其进行分析,看看它花费的时间在哪里。这是几乎所有“为什么我的Matlab代码变慢?”的最佳第一手段。问题

clear all
profile on -timer real
foo(args);
profile report
%read the report and save a screencap
clear all
profile clear
bar(args);
profile report

结束了建议。这开始了猜测。

这两个电话中有两个不同的东西。有工作区互动。从命令行调用foo()可能会在工作区中填充变量“ans”。从bar()调用时,将设置ans,但在bar()返回时立即清除。此外,foo()可能正在使用evalin()/ assignin()来查看调用堆栈中的工作空间,并且它可能与基本工作空间中分配的变量进行交互。 bar()函数有一个干净的工作区。

取决于bar.m的位置,它实际上可能正在调用不同的foo(),或者可能稍微不同地解析它。在两个上下文中使用“which foo”检查路径解析。

根据“args”的定义方式,foo可能会看到不同的inputname()。

此外,foo()可能包含检查是否从基础工作区调用它的病态代码,或者是否由特定名称的函数调用它,并且基于此行为不同。

尽管如此,这些应该主要是次要的互动,不应该导致该订单的减速。我怀疑还有其他事情正在发生,也许只是通过稍微不同的呼叫上下文暴露出来。使用bar()添加间接级别不应该是答案。看看剖析器的内容,并从那里开始。重现的确切代码将有助于从社区获得帮助。