简体   繁体   English

ode45 mex文件运行缓慢

[英]ode45 mex file runs slow

This is the function trial2 which creates the system of differential equations: 这是创建微分方程组的函数trial2

function xdot=trial2(t,x) 
delta=0.1045;epsilon=0.0048685; 
xdot=[x(2);(-delta-epsilon*cos(t))*x(1)-0.7*delta*abs(x(1))];

Then, I try and solve this using ode45 : 然后,我尝试使用ode45解决此ode45

[t,x]=ode45('trial2',[0 10000000],[0;1]);
plot(t,x(:,1),'r');

But, this takes approximately 15 minutes. 但是,这大约需要15分钟。 So I tried to improve the run time by creating a mex file. 因此,我尝试通过创建一个mex文件来改善运行时间。 I found an ode45 mex equivalent function ode45eq.c . 我找到了ode45 mex等效函数ode45eq.c Then, I tried to solve by: 然后,我尝试通过以下方法解决:

mex ode45eq.c;
[t,x]=ode45eq('trial2',[0 10000000],[0;1]);
plot(t,x(:,1),'r');

But this seems to run even slower. 但这似乎运行得更慢。 What could be the reason and how can I improve the run time to 2–3 minutes? 原因可能是什么?如何将运行时间缩短到2至3分钟? I have to perform a lot of these computations. 我必须执行很多这些计算。 Also, is it worth creating a standalone C++ file to solve the problem faster? 另外,值得创建一个独立的C ++文件来更快地解决问题吗?

Also, I am running this on an Intel i5 processor 64-bit system with 8 gb RAM. 另外,我正在具有8 GB RAM的Intel i5处理器64位系统上运行此程序。 How much gain in speed do you think I can get if I move to a better processor with say 16 gb RAM? 如果我转向具有16 GB RAM的更好的处理器,您认为我可以获得多少速度提升?

With current versions of Matlab, it's very unlikely that you'll see any performance improvement by compiling ode45 to C/C++ mex . 在当前版本的Matlab中,通过将ode45编译为C / C ++ mex几乎看不到任何性能改进。 In fact, the compiled version will almost certainly be slower as you found. 实际上,编译版本几乎可以肯定会像您发现的那样慢。 There's a good reason that ode45 is written in pure Matlab, as opposed to being compiled down to a native C function: it has to call user functions written in Matlab on every iteration. 有一个很好的理由认为ode45是用纯Matlab编写的,而不是被编译为本机C函数:它必须在每次迭代中调用用Matlab编写的用户函数。 Additionally, Matlab's ode45 is a very dynamic function that is capable of interacting with the Matlab environment in many ways during the course of integration (plotting output functions, event detection, interpolation, etc.). 此外,Matlab的ode45是一个非常动态的功能,能够在集成过程中以多​​种方式与Matlab环境进行交互(绘图输出功能,事件检测,插值等)。 It's also probably more straightforward to safely handle dynamic memory allocation in Matlab, than in C. 安全地在Matlab中处理动态内存分配比在C中更直接。

Your C code calls your user function via mexCallMATLAB . 您的C代码通过mexCallMATLAB调用您的用户函数。 This function is not really meant for repeated calls , especially if they transfer data back and forth. 此功能并非真正适用于重复调用 ,尤其是当它们来回传输数据时。 Doing what you're trying to do would likely require new mex APIs and possibly changes to the Matlab language. 做您想做的事情可能需要新的mex API,并可能需要更改Matlab语言。

If you want faster numerical integration, you're going to have to give up the convenience of being able to write your integrations functions (ie, trial2 in your example) in Matlab. 如果您想更快地进行数值积分,您将不得不放弃能够在Matlab中编写积分函数(例如, trial2中的trial2 )的便利。 You'll need to "hard code" your integration functions and compile them along with the integration scheme itself. 您将需要对集成函数进行“硬编码”,并与集成方案本身一起对其进行编译。 With a detailed knowledge about your problem, and decent programming skills, you can write a tight integration loop and it may be possible to achieve an order of magnitude speedup in some cases. 有了关于您的问题的详细知识和良好的编程技巧,您就可以编写一个紧密的集成循环,并且在某些情况下有可能实现数量级的加速。

Lastly, your trial2 function has an absolute value as well as an oscillating trigonometric function in it. 最后,您的trial2函数具有绝对值以及其中的振荡三角函数。 Is this differential equation stiff ? 这个微分方程僵硬吗? Have you tried other solvers, eg, ode15s ? 您是否尝试过其他求解器,例如ode15s Compare the outputs even over a shorter time period. 即使在较短的时间内也要比较输出。 And you may find that you get a bit of a speed-up (~25% on my machine) if you use the modern way of passing function handles instead of strings to ode45 : 如果您使用现代的方法将函数句柄而不是字符串传递给ode45可能会发现速度有所提高(在我的机器上约为25%):

[t,x] = ode45(@trial2,[0 10000000],[0;1]);

The trial2 function can still be in a separate M-file or it can be a sub-function in the same file with your call to ode45 (this file need to be a function file, not a script of course). trial2函数仍可以位于单独的M文件中,或者可以是与调用ode45调用相同的文件中的ode45 (此文件必须是功能文件,而不是脚本)。

What you did is basically replacing the todays implementation with the implementation of 1993, you have shown that mathworks did a great job improving the performance of the ode45 solver. 您所做的基本上是将今天的实现替换为1993年的实现,您已经证明mathworks在改善ode45求解器的性能方面做得很好。

I don't see any possibility to improve the performance in this case, you can assume that such a fundamental part of MATLAB like ode45 is implemented in a optimal way, replacing it with some other code to mex it is not the solution. 在这种情况下,我看不到有提高性能的任何可能性,您可以假设像ode45这样的MATLAB基础部分是以最佳方式实现的,用其他代码替代它来解决问题并不是解决方案。 Everything you could gain using a mex function is cutting of the overhead of input/output handling which is implemented in m. 使用mex函数可以获得的所有好处就是减少了以m为单位实现的输入/输出处理的开销。 Probably less than 0.1s execution time. 执行时间可能少于0.1s。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM