ode45 mex文件运行缓慢

时间:2014-07-20 13:05:27

标签: performance matlab mex

这是创建微分方程组的函数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))];

然后,我尝试使用ode45解决此问题:

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

但是,大约需要15分钟。所以我尝试通过创建一个mex文件来改善运行时间。我找到了ode45 mex等效函数ode45eq.c。然后,我试图解决:

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

但这似乎运行得更慢。可能是什么原因,如何将运行时间提高到2-3分钟?我必须执行很多这些计算。此外,是否值得创建一个独立的C ++文件来更快地解决问题?

此外,我在具有8 GB RAM的Intel i5处理器64位系统上运行此功能。如果我转向更好的16 gb RAM处理器,你认为我能获得多少速度?

2 个答案:

答案 0 :(得分:1)

使用当前版本的Matlab,通过将ode45编译为C / C ++ mex,您不太可能看到任何性能提升。实际上,编译后的版本几乎肯定会慢一些。有一个很好的理由ode45是用纯Matlab编写的,而不是编译成本机C函数:它必须在每次迭代时调用用Matlab编写的用户函数。另外,Matlab的ode45是一个非常动态的函数,能够在集成过程中以多​​种方式与Matlab环境交互(绘制输出函数,事件检测,插值等)。在Matlab中安全处理动态内存分配可能比在C中更直接。

您的C代码通过mexCallMATLAB调用您的用户功能。此函数为not really meant for repeated calls,特别是如果它们来回传输数据。做你正在尝试做的事情可能需要新的mex API,并可能需要改变Matlab语言。

如果您想要更快的数值积分,您将不得不放弃在Matlab中编写集成函数(即示例中的trial2)的便利性。您需要"硬编码"您的集成功能并将它们与集成方案本身一起编译。通过详细了解您的问题和良好的编程技巧,您可以编写一个紧密的集成循环,在某些情况下可以实现一个数量级的加速。

最后,您的trial2函数具有绝对值以及其中的振荡三角函数。这个微分方程是stiff吗?您是否尝试过其他求解器,例如ode15s?即使在较短的时间内也能比较输出。如果你使用现代的方法将函数句柄而不是字符串传递给ode45,你可能会发现你获得了一点加速(在我的机器上约为25%):

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

trial2函数仍然可以在一个单独的M文件中,或者它可以是调用ode45的同一文件中的子函数(此文件需要是一个函数文件,当然不是剧本。)

答案 1 :(得分:0)

你所做的基本上是用1993年的实现取代今天的实现,你已经证明mathworks在提高ode45求解器的性能方面做得很好。

我认为在这种情况下没有任何改善性能的可能性,你可以假设像ode45这样的MATLAB这样一个基本部分是以最佳的方式实现的,用其他代码代替它来代替它不是解决方案。使用mex函数可以获得的一切都是减少输入/输出处理的开销,这是以m为单位实现的。可能小于0.1秒的执行时间。