- 在线时间
- 13 小时
- 最后登录
- 2013-12-8
- 注册时间
- 2010-5-13
- 听众数
- 3
- 收听数
- 0
- 能力
- 0 分
- 体力
- 399 点
- 威望
- 11 点
- 阅读权限
- 30
- 积分
- 282
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 97
- 主题
- 45
- 精华
- 0
- 分享
- 0
- 好友
- 1
升级   91% TA的每日心情 | 难过 2012-8-27 18:22 |
|---|
签到天数: 1 天 [LV.1]初来乍到
|
本帖最后由 forcal 于 2010-10-12 21:46 编辑
& N4 A( i0 l/ p: ]
, l$ w, b& [+ Y: l/ E我正在练手设计的FcMath库也打算以矩阵运算为基础,设计一些专门的函数对数组元素集中运算,运行效率确实有所提高(甚至有些涉及矩阵的算法比matlab还快),代码也简洁了,但不知这是不是矢量化?( X& b0 g% W6 M) n" [- P/ s0 T
R9 ]% X( T- l) w( D脚本运行效率应该取决于函数调度效率、对象管理效率和函数内部算法的实现。2 I2 }. K* c" R& g0 D
5 z/ g; @$ ~! v% R& g: X8 g: W0 Y
我感觉,matlab的函数调度效率较低,对象管理效率这个不好说,但一些函数内部的设计比较优秀。故有些Forcal代码比matlab快,而有些慢。& _/ w; G8 X6 t2 V
0 f0 t, L7 A. S+ p以下例子体现了Forcal和matlab的效率差别所在。
, O# i* H/ R4 W
" \: r- t5 `4 H) k这个matlab程序段是网友lin2009 给出的,理论结果是每个元素均为275000。- clear all
9 F$ ~* L1 A6 c - clc4 J\" L) O6 e' E\" _5 V2 `
- tic/ {$ K' x: d+ J5 H4 K
- k = zeros(5,5); % //生成5×5全0矩阵, G5 |3 |# R5 k/ D [( o
- % 循环计算以下程序段1000 00次:
' B' U& D% v5 e* ?2 p) ~; K - for m = 1:1000 00
$ X# ?. T1 y4 {: h - a = rand(5,7);
: {! K4 d6 O/ b - b = rand(7,5);%//生成5×7矩阵a,7×5矩阵b,用0~1之间的随机数初始化
. b4 |9 A; q+ E& O; M - k = k + a * b + a(1:5, 2:6) * b(2:6, 1:5) - a(:, 7) * b(3, :);1 R5 B2 m0 j$ e8 D4 D$ ]/ ]
- end
- B4 v( b* P2 m7 ^ - k
& g: [6 r& r$ @% y6 ]5 \2 p - toc
复制代码
7 ]6 L) ?" E' K5 b! l3 K. w& ]$ ^Forcal代码1:运行稍快的代码,比matlab约快10%吧?7 R$ D1 C" s4 B9 v# Z) ?% s
 - !using["math","sys"];! U L6 Y+ ^1 t7 Z9 p
- mvar:% s. y; Y3 |- W- h( f+ Q% s
- t0=clock(),
- 8 O3 l6 B, T; _# r
- oo{k=zeros[5,5]},
- 8 J; o' Y% y1 w
- i=0,((i++)<100000).while{. c! P8 U' `0 v7 ^* ^
- oo{
- 5 f( s( Z- ~6 k3 j. \2 R, z
- a=rand[5,7], b=rand[7,5],
- 5 ^9 w- E, Z4 U. p
- k.oset[k+a*b+a.subg(0,4:1,5)*b.subg(1,5:0,4)-a.subg(neg:6)*b.subg(3:neg)]
- - W% @8 I; L2 U
- }- r1 U8 J: t, P\\" h; {/ R
- },; `0 F' P! m! c5 |3 R
- k.outm(),' s4 W; r- I; t) H' H
- [clock()-t0]/1000;
在我的电脑上运行时间为3.344秒。
9 b( l1 a6 C! k8 u/ d9 ^+ D) Z6 Z' O, n5 X" W$ a2 X P
Forcal代码2:比较好看些的代码,似乎也比matlab稍快吧?* h9 @ E- Q' o4 E0 N# p
 - !using["math","sys"];0 c; T! s: J# I7 @ l& Q
- (:t0,k,i,a,b)=! e8 X% D8 p5 T6 k: j9 t9 o: U. _& `
- {5 c& I! D* p* e
- t0=clock(),
- . P, w8 ]* f8 i# v
- oo{k=zeros[5,5]},
- 3 E$ n4 l4 T2 h2 U [. v: f+ Z
- i=0,((i++)<100000).while{\\" E6 L: a2 }; O0 U8 o
- oo{2 t' C! z+ J7 Y4 O4 I( @; D
- a=rand[5,7], b=rand[7,5],5 T/ U5 g. p6 f0 P) i* N# C9 r/ h
- k.=k+a*b+a(0,4:1,5)*b(1,5:0,4)-a(neg:6)*b(3:neg)3 N\\" w& F' }! ~6 I0 m* U1 |9 r
- }
- 9 e4 e0 G+ ]: y3 D
- },# Z7 u5 |2 U5 M- {
- k.outm(),
- 3 r; F b4 c- s/ C. S5 v8 c8 {
- [clock()-t0]/1000
- ) I4 ]7 F! f W6 e& J1 o( z
- };
在我的电脑上运行时间为3.579秒。
& i" ?" T$ t- p$ y) I4 G( l; D- e+ c3 N4 i2 l& U
例子2:! \) x% _. O# J, N# u, i
一段程序的Forcal实现:- }7 n8 G7 v4 J: ~1 f3 y" H
- //用C++代码描述为:* E7 _- Z0 z* _0 @8 Q4 I
- s=0.0;
, o- O3 Y; x, e, a\" P- T$ D - for(x=0.0;x<=1.0;x=x+0.0011) . f# {5 u$ p/ L S8 g. A4 P
- {
. _; C8 L/ z$ ?0 w: H0 h' q, q - for(y=1.0;y<=2.0;y=y+0.0009)
. F$ `, i. R9 ] - {
0 D/ e8 g: L2 r2 S5 M - s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
4 z% q5 F# t6 Y5 a - }( C' P8 q- g) n2 ?6 N
- }
复制代码 结果:
# q% t% c8 |. C0 e1008606.64947441
9 w! v6 A% z; m6 h& C& Z0.609 //时间 f5 {: a& T x; ?* p. ]
5 E. a* \ X5 a! V0 Y
这个matlab程序段是网友yycs001给出的。4 ?1 M4 b" [, M: a/ v5 \ N6 @
- %file speedtest.m
5 Q, M, J3 ?( V% H/ Z - function speedtest- h2 _+ A/ h9 G. l) m) t
- format long\" U6 e1 G' F7 x7 \) |- F
- tic' J4 U. d1 O\" z
- [x,y]=meshgrid(0:0.0011:1,1:0.0009:2);
+ P8 m' W& A0 E - s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))- q8 o9 r/ [6 {9 } N
- toc
复制代码
6 `9 }; n: f1 }( y# Y& | S* UForcal代码1:**数组求和函数Sum,完全矢量化的代码( H7 t& v3 d1 ?5 g' \6 a, o) R+ b6 q
 - !using["math","sys"];
- ; k7 H2 S# A9 N9 }
- mvar:, m( S6 m/ L) L9 G
- t=clock(),\\" v! E3 Y8 h7 v# K d% W9 Z: I
- oo{
- 4 V- e+ q& k, r, Z! x) l\\" m C. R
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
- 4 x7 F' d( O' ?\\" I
- Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2)))))),0]
- ! C# a! Q+ o4 [3 n, D
- };- |6 [/ `* S0 a8 w& j0 b1 T
- [clock()-t]/1000;
结果:+ _! r9 H' G, s- q* L' |
1008606.649474411 |$ V! s# Q0 H2 }% p
0.625 //时间 [* H7 W( K& o8 n
; _. r6 ] e( C4 W0 I) M+ s
或者这个,与上面效率差别不大:
- X6 T! Y3 H7 t9 [: g1 l - !using["math","sys"];
- 3 W$ Z* `( X' U/ Y
- mvar:
- ) K! J1 y V) v
- t=clock(),
- 0 G3 h7 }6 X2 N, D0 j
- oo{
- / U. T- l) L& w6 |0 i5 W H7 U2 S( K8 ?
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],# r% V) s% p5 |9 I! R
- Sum[Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2))))))]]) F3 n\\" z) s8 ~* ?; M
- };
- ' ^- _' L+ ^/ `/ _2 M
- [clock()-t]/1000;
+ o1 o [' y# Z3 E9 J$ ]- ]Forcal代码2:求和函数sum,非矢量化代码
0 w( K0 ^1 b g+ V- f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
2 d5 X' s0 o) |! n# D4 o - sum["f",0,1,0.0011,1,2,0.0009];
复制代码 结果:) o- A( U+ O7 I4 \4 }. G" o
1008606.64947441
) d6 ~: X. c! Q5 r5 y0.719 //时间
+ T% O$ w, s! O
0 v- |! M; x$ [ v A/ l$ xForcal代码3:while循环
3 {" R8 C$ S6 p6 ~+ {: l- mvar:
4 K5 i5 j) e) k9 d - t=sys::clock();$ v7 u4 p. x5 a9 i
- s=0,x=0, 8 o0 Z* b* X% Z
- while{x<=1, //while循环算法; ) N. A5 I! U+ x# x7 G8 n+ p( N
- y=1, ) n0 r) b) Y% H7 T
- while{y<=2, 6 d( k- u. a' Q
- s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))), 8 v1 \4 l* O/ G7 G7 s S. o+ M+ \ ^# y
- y=y+0.0009 . ]; J\" Z/ ^1 ^3 r% J5 l8 r5 l
- },
2 f2 o4 i# A, Z, e: S - x=x+0.0011
\" g& I+ V- u9 S - },
; U8 V4 S7 d) V7 S# x3 \9 C% w& V - s;* G( e. E\" A J0 e6 E
- [sys::clock()-t]/1000;
复制代码 结果:
6 ^7 w6 _, a% t! P$ a1008606.64947441! J& T4 B' U( _
0.734 //时间
4 e+ R* q5 N q I1 X' o& U, o$ J/ V8 _# u
大家可下载OpenFC进行测试:http://www.forcal.net/xiazai/forcal9/openfc32w.rar! ]9 s2 X* B( z1 G3 W( t) d
( I! r, B* a: X% E
注意Forcal的矢量化代码第一次运行有时效率较低。/ T# `1 O0 o% O/ ]# f2 S
1 T2 [" ]6 X) j/ F9 e6 ]" c9 h6 a例子1中Forcal和matlab都是矢量化代码,但matlab跑不过Forcal。该例子的特点是函数调用频繁,临时变量生成多,但矩阵很小,矩阵的各种函数运行时耗时较少。故说明Forcal函数调用+变量管理效率优于matlab。8 X. b2 ~8 D$ G; Z7 M
" ?* q5 ?( [5 b: o- t( P例子2中Forcal的矢量化代码是最快的,但与matlab的矢量化代码相比仍有差距。该例子的特点是函数调用少,临时变量也少,但矩阵大。故说明Forcal的各种矩阵函数Sin、Cos及矩阵的加减运算等函数的内部设计不及matlab。
8 a; ~9 u( S4 {' Q5 O$ c% J. y# I" R
如能在函数内部设计上下点功夫,例子2超越matlab也是可能的。在这方面,期待高手们的指点。
y j7 G" u9 O$ ]; z" y$ n$ v$ t" c& E) U. \
如果例子2速度也超越了matlab ,matlab矢量化的神秘面纱就揭开了。
( u! G0 p; q) R* l
5 T8 _* A1 T( j' V顺便说一下,例子1如果用C++的运算符重载来实现,速度将比Forcal慢一些,也就是说,在涉及运算符重载时,脚本的效率有时比C++还要高些。. Q' B5 g+ @0 {* c8 [9 {
|
|