关于matlab代码矢量化的理解
代码矢量化是matlab的精髓,其基本特点是运行速度快和代码简洁,它是如何实现的?按我的理解,代码矢量化的本质就是设计专门的函数对数组元素集中运算,这样可提高运行速度,同时兼有代码简洁的特点。
对matlab的理解比较肤浅,但也确实看不出有更深意义的东西,望解惑。
大家有什么看法,愿畅所欲言。
我 正在 学 Matlab 软件!~~ ??????????????????:) 顶。。。。。。。。。。。。。。。。。。。。。。 ,,,顶顶更健康! 本帖最后由 forcal 于 2010-10-12 21:46 编辑
我正在练手设计的FcMath库也打算以矩阵运算为基础,设计一些专门的函数对数组元素集中运算,运行效率确实有所提高(甚至有些涉及矩阵的算法比matlab还快),代码也简洁了,但不知这是不是矢量化?
脚本运行效率应该取决于函数调度效率、对象管理效率和函数内部算法的实现。
我感觉,matlab的函数调度效率较低,对象管理效率这个不好说,但一些函数内部的设计比较优秀。故有些Forcal代码比matlab快,而有些慢。
以下例子体现了Forcal和matlab的效率差别所在。
这个matlab程序段是网友lin2009 给出的,理论结果是每个元素均为275000。clear all
clc
tic
k = zeros(5,5); % //生成5×5全0矩阵
% 循环计算以下程序段1000 00次:
for m = 1:1000 00
a = rand(5,7);
b = rand(7,5);%//生成5×7矩阵a,7×5矩阵b,用0~1之间的随机数初始化
k = k + a * b + a(1:5, 2:6) * b(2:6, 1:5) - a(:, 7) * b(3, :);
end
k
toc
Forcal代码1:运行稍快的代码,比matlab约快10%吧?
!using["math","sys"];
mvar:
t0=clock(),
oo{k=zeros},
i=0,((i++)<100000).while{
oo{
a=rand, b=rand,
k.oset
}
},
k.outm(),
/1000;在我的电脑上运行时间为3.344秒。
Forcal代码2:比较好看些的代码,似乎也比matlab稍快吧?
!using["math","sys"];
(:t0,k,i,a,b)=
{
t0=clock(),
oo{k=zeros},
i=0,((i++)<100000).while{
oo{
a=rand, b=rand,
k.=k+a*b+a(0,4:1,5)*b(1,5:0,4)-a(neg:6)*b(3:neg)
}
},
k.outm(),
/1000
};在我的电脑上运行时间为3.579秒。
例子2:
一段程序的Forcal实现:
//用C++代码描述为:
s=0.0;
for(x=0.0;x<=1.0;x=x+0.0011)
{
for(y=1.0;y<=2.0;y=y+0.0009)
{
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
}
} 结果:
1008606.64947441
0.609 //时间
这个matlab程序段是网友yycs001给出的。
%file speedtest.m
function speedtest
format long
tic
=meshgrid(0:0.0011:1,1:0.0009:2);
s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))
toc
Forcal代码1:**数组求和函数Sum,完全矢量化的代码
!using["math","sys"];
mvar:
t=clock(),
oo{
ndgrid,
Sum
};
/1000;结果:
1008606.64947441
0.625 //时间
或者这个,与上面效率差别不大:
!using["math","sys"];
mvar:
t=clock(),
oo{
ndgrid,
Sum]
};
/1000;
Forcal代码2:求和函数sum,非矢量化代码
f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
sum["f",0,1,0.0011,1,2,0.0009];结果:
1008606.64947441
0.719 //时间
Forcal代码3:while循环
mvar:
t=sys::clock();
s=0,x=0,
while{x<=1, //while循环算法;
y=1,
while{y<=2,
s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))),
y=y+0.0009
},
x=x+0.0011
},
s;
/1000;结果:
1008606.64947441
0.734 //时间
大家可下载OpenFC进行测试:http://www.forcal.net/xiazai/forcal9/openfc32w.rar
注意Forcal的矢量化代码第一次运行有时效率较低。
例子1中Forcal和matlab都是矢量化代码,但matlab跑不过Forcal。该例子的特点是函数调用频繁,临时变量生成多,但矩阵很小,矩阵的各种函数运行时耗时较少。故说明Forcal函数调用+变量管理效率优于matlab。
例子2中Forcal的矢量化代码是最快的,但与matlab的矢量化代码相比仍有差距。该例子的特点是函数调用少,临时变量也少,但矩阵大。故说明Forcal的各种矩阵函数Sin、Cos及矩阵的加减运算等函数的内部设计不及matlab。
如能在函数内部设计上下点功夫,例子2超越matlab也是可能的。在这方面,期待高手们的指点。
如果例子2速度也超越了matlab ,matlab矢量化的神秘面纱就揭开了。
顺便说一下,例子1如果用C++的运算符重载来实现,速度将比Forcal慢一些,也就是说,在涉及运算符重载时,脚本的效率有时比C++还要高些。
讨论有益!以下是在其他论坛的讨论帖子:
simwe:http://forum.simwe.com/thread-952532-1-3.html
csdn:http://topic.csdn.net/u/20101006/21/2ed9e5c1-cc9f-4623-b1c0-ebd5d1b5a98a.html
cadn:http://topic.csdn.net/u/20101010/15/3bcf2fe0-0abd-4c29-b854-b1d007b16863.html
参考:http://bbs.emath.ac.cn/thread-2709-1-1.html
我在多个帖子中有不同说明,但将这些说明再集中到一个帖子中比较麻烦,大家相互参考一下,看能否把这个问题解决了。 参考:http://bbs.emath.ac.cn/thread-2727-1-1.html
关于最快速的矩阵乘实现的讨论。
页:
[1]