Matlab:从循环中重复调用相同的mex函数会导致过多的开销吗? [英] Matlab: Does calling the same mex function repeatedly from a loop incur too much overhead?

查看:270
本文介绍了Matlab:从循环中重复调用相同的mex函数会导致过多的开销吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些需要加速的Matlab代码.通过分析,我确定了某个特定的功能是减慢执行速度的罪魁祸首.在一个循环中,该函数被调用数十万次.

I have some Matlab code which needs to be speeded up. Through profiling, I've identified a particular function as the culprit in slowing down the execution. This function is called hundreds of thousands of times within a loop.

我的第一个想法是将函数转换为mex(使用Matlab Coder)以加快速度.但是,通常的编程常识告诉我Matlab与mex代码之间的接口会导致一些开销,这意味着数千次调用此mex函数可能不是一个好主意.这样对吗?还是当反复调用相同的mex来消除开销时,Matlab会发挥一些魔力吗?

My first thought was to convert the function to mex (using Matlab Coder) to speed it up. However, common programming sense tells me the interface between Matlab and the mex code would lead to some overhead, which means calling this mex function thousands of times might not be a good idea. Is this correct? Or does Matlab do some magic when it's the same mex being called repeatedly to remove the overhead?

如果有 的大量开销,我正在考虑重组代码,以便将循环添加到函数本身,然后然后创建一个混合代码.在此之前,我想验证一下我的假设,以证明在此花费的时间是合理的.

If there is significant overhead, I'm thinking of restructuring the code so as to add the loop to the function itself and then creating a mex of that. Before doing that, I would like to validate my assumption to justify the time spent on this.

更新:

我尝试了@angainor的建议,并使用以下代码创建了donothing.m:

I tried @angainor's suggestion, and created donothing.m with the following code:

function nothing = donothing(dummy) %#codegen
nothing = dummy;
end

然后,我以此创建了一个mex函数donothing_mex,并尝试了以下代码:

Then, I created a mex function from this as donothing_mex, and tried the following code:

tic;
for i=1:1000000
    donothing_mex(5);
end
toc;

结果是,对该函数的一百万次调用花费了大约9秒的时间.对于我们的目的来说,这不是一个很大的开销,因此,现在我想我将把被调用的函数单独转换为mex.然而,回想起来,从执行约一百万次的循环中调用一个函数似乎是一个很愚蠢的主意,考虑到这是性能关键代码,因此将循环移至mex函数仍然在书中,但优先级要低得多.

The result was that a million calls to the function took about 9 seconds. This is not a significant overhead for our purposes, so for now I think I will convert the called function alone to mex. However, calling a function from a loop that executes about a million times does seem a pretty stupid idea in retrospect, considering this is performance critical code, so moving the loop to the mex function is still in the books, but with much lesser priority.

推荐答案

与往常一样,这完全取决于您在MEX文件中所做的工作量.调用MEX函数的开销是恒定的,并且不依赖于例如,问题的大小.这意味着将将参数复制到新的临时数组.因此,如果足够工作,将不会显示调用MEX文件的MATLAB开销.无论如何,以我的经验,MEX调用开销仅在第一次调用mex函数时才有意义-必须加载动态库,解析符号等.后续的MEX调用开销很小且非常有效.

As usual, it all depends on the amount of work you do in the MEX file.. The overhead of calling MEX function is constant and does not depend on e.g., the problem size. It means that arguments are not copied to new, temporary arrays. Hence, if it is enough work, the MATLAB overhead of calling the MEX file will not show. Anyway, in my experience the MEX call overhead is significant only for the first time the mex function is called - the dynamic library has to be loaded, symbols resolved etc. Subsequent MEX calls have very little overhead and are very efficient.

由于这种高级语言的本质,MATLAB中的几乎所有东西都与一些开销有关.除非您有代码,否则您可以确定已使用JIT完全编译了该代码(但随后不需要mex文件:))因此,您可以选择一个开销而不是另一个开销.

Almost everything in MATLAB is connected with some overhead due to the nature of this high-level language. Unless you have a code, which you are sure is fully compiled with JIT (but then you do not need a mex file :)) So you have a choice of one overhead over the other..

总结一下-我不会太害怕MEX调用开销.

So sum up - I would not be too scared of MEX calling overhead.

编辑正如在这里和其他地方经常听到的那样,在任何特定情况下,唯一合理的做法当然是 BENCHMARK 并检查一下自己.您可以通过编写简单的MEX函数轻松估算MEX通话费用:

Edit As often heard here and elsewhere, the only reasonable thing to do in any particular case is of course BENCHMARK and check it for your self. You can easily estimate the MEX call overhead by writing a trivial MEX function:

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) 
{      
}

在我的计算机上,您可以得到

On my computer you get

tic; for i=1:1000000; mexFun; end; toc
Elapsed time is 2.104849 seconds.

每个MEX通话费用为2e-6s.添加您的代码,计时,看看开销是否在可接受的水平.

That is 2e-6s overhead per MEX call. Add your code, time it and see, if the overhead is at acceptable level, or not.

正如Andrew Janke在下面指出的(谢谢!),MEX函数的开销显然取决于传递给MEX函数的参数数量.这是一个很小的依赖,但确实存在:

As Andrew Janke noted below (thanks!), the MEX function overhead apparently depends on the number of arguments you pass to the MEX function. It is a small dependence, but it is there:

a = ones(1000,1);
tic; for i=1:1000000; mexFun(a); end; toc
Elapsed time is 2.41 seconds.

它与a的大小无关:

a = ones(1000000,1);
tic; for i=1:1000000; mexFun(a); end; toc
Elapsed time is 2.41805 seconds.

但这与参数数量有关

a = ones(1000000,1);
b = ones(1000000,1);
tic; for i=1:1000000; mexFun(a, b); end; toc
Elapsed time is 2.690237 seconds.

因此您可能需要在测试中考虑到这一点.

So you might want to take that into account in your tests.

这篇关于Matlab:从循环中重复调用相同的mex函数会导致过多的开销吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆