- 在线时间
- 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 编辑
& z' @! d* b |7 x/ u" _5 Z+ _" f. W* ^
我正在练手设计的FcMath库也打算以矩阵运算为基础,设计一些专门的函数对数组元素集中运算,运行效率确实有所提高(甚至有些涉及矩阵的算法比matlab还快),代码也简洁了,但不知这是不是矢量化?; j: o9 v! B+ e/ M* B
9 [; [! t Z* f/ S脚本运行效率应该取决于函数调度效率、对象管理效率和函数内部算法的实现。
$ C! u1 u% `% _) V; t% u/ a) P1 Z$ v9 ~# U/ q W9 M2 R K
我感觉,matlab的函数调度效率较低,对象管理效率这个不好说,但一些函数内部的设计比较优秀。故有些Forcal代码比matlab快,而有些慢。$ B4 L2 U7 m6 n0 `' Z- B# c& }
' F* l1 X0 G% b: R
以下例子体现了Forcal和matlab的效率差别所在。/ S+ P: V/ L8 I) @) K/ @7 s
1 S! p2 J8 x. j R这个matlab程序段是网友lin2009 给出的,理论结果是每个元素均为275000。- clear all
\" `& Q# e. {1 b* k) V2 C( Z - clc* c4 R0 R$ T: O( m$ X! D
- tic+ C. b/ \ @, h: w B9 Q$ F3 ?
- k = zeros(5,5); % //生成5×5全0矩阵
& L; R- r D- o6 N! ^) _+ T# o5 \- M$ a - % 循环计算以下程序段1000 00次:
\" }\" q/ J9 \ L% [; z9 T - for m = 1:1000 00& q5 X5 J% a4 \' g( |
- a = rand(5,7);\" `: g# h- h& {7 Y
- b = rand(7,5);%//生成5×7矩阵a,7×5矩阵b,用0~1之间的随机数初始化
4 ?9 o- K' m! Z+ v) h - k = k + a * b + a(1:5, 2:6) * b(2:6, 1:5) - a(:, 7) * b(3, :);* T) o6 F1 F) x
- end
' N: j; c# p, j' a5 @ - k
% H6 f7 t9 F\" ]' _. @ - toc
复制代码
& B2 I4 Q, [" N! l" jForcal代码1:运行稍快的代码,比matlab约快10%吧?
7 D% n5 H/ H* Z0 n7 t Z: L& t# V - !using["math","sys"];2 Z, h\\" E: r% E* ]
- mvar:
- ' Y0 D* U2 c/ k; f7 J% Y- x
- t0=clock(),+ c& }- y4 O. X0 Q/ }9 k( c
- oo{k=zeros[5,5]},
- / N# ~) s' l- c/ e
- i=0,((i++)<100000).while{: T) i& g5 w2 s
- oo{
- - n8 @' s) i' @! b1 o
- a=rand[5,7], b=rand[7,5],
- 2 y0 x1 X7 D3 V. V0 B
- 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)]9 I7 q% f+ v7 ~6 H
- }' X; u) O& H) k
- },
- 8 p4 u* e, b; W+ n5 ^' r. H* A
- k.outm(),
- % x/ T4 H( ~% x+ `' s/ _0 k8 R
- [clock()-t0]/1000;
在我的电脑上运行时间为3.344秒。8 w8 A3 W7 K% t% c& X' Z* p% ?
6 m% r0 n. A! P: ~0 i; t
Forcal代码2:比较好看些的代码,似乎也比matlab稍快吧?# w& B( O1 ?- b) e" @# e
 - !using["math","sys"];) N9 [5 j& y% q( J- I
- (:t0,k,i,a,b)=
- + e! K G6 h1 |! b! ]* \
- {% N\\" t! n$ X$ e$ {9 V A
- t0=clock(),
- 7 C1 e6 b# q& _, u8 ~$ q. [' L
- oo{k=zeros[5,5]},
- 9 X; k t, l* D; C7 n! I
- i=0,((i++)<100000).while{
- 7 b2 p5 b3 g& {; k+ i( W
- oo{
- 0 I$ w9 L$ P) ?6 w
- a=rand[5,7], b=rand[7,5],
- 0 F- ^\\" N2 L& I% P
- k.=k+a*b+a(0,4:1,5)*b(1,5:0,4)-a(neg:6)*b(3:neg)6 }: ?* w- K) c' f3 d
- }
- , ^9 Y! Q2 E8 K- m0 R3 t3 m) [
- },
- {1 A5 f2 O4 f/ ]: ~! P
- k.outm(),
- 7 r- h' M9 G) O* C5 z/ Y7 E+ X
- [clock()-t0]/10009 j$ h6 C, T$ `: a) ~8 U7 V
- };
在我的电脑上运行时间为3.579秒。
$ ]- j% u* K- ^$ u. n* q2 |" _6 l& h) _$ ?
例子2:
7 r. n2 ~+ D9 {9 U& R一段程序的Forcal实现:
" Q: G# q6 ^& ], q8 J6 u: s- //用C++代码描述为:% K' g( `3 H% Z2 D4 p
- s=0.0; # t3 i* ?5 ]\" ^* X& C1 `1 m' p
- for(x=0.0;x<=1.0;x=x+0.0011) . @4 M$ _+ a8 l
- {
6 ?) O3 u6 d- L2 k6 @3 C - for(y=1.0;y<=2.0;y=y+0.0009)9 W8 @2 N. r& c' Q; D
- {; K, {1 o7 I2 b
- s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
; H1 B0 k/ b1 P( [* H - }
' V3 V( l3 h: B+ r: j5 _% k - }
复制代码 结果:" ?. E6 a L6 O( l4 Z7 D4 p4 h+ p9 W
1008606.64947441% v1 h E D7 h: {5 z8 N
0.609 //时间* X& C8 w% H& |) K( H6 Y
5 `2 ?( w' v; d5 J$ e$ ]; i这个matlab程序段是网友yycs001给出的。' N5 n, C5 z6 S4 l$ l9 o; O: ?' y
- %file speedtest.m0 A$ t, J8 e% e# ^* V1 J
- function speedtest
; r- _1 V) ~\" W' J' Q0 B1 H - format long
- Z, G B6 _) R8 F' u. ^/ S - tic' ^& E' V5 v9 E
- [x,y]=meshgrid(0:0.0011:1,1:0.0009:2);' I5 G6 ^8 J4 X5 L( V8 w! y
- s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))0 k) `* p* H( ^, C% |) X4 U8 r
- toc
复制代码 ( f e* v: i* ^% K0 B
Forcal代码1:**数组求和函数Sum,完全矢量化的代码
1 g7 ]5 \. Z: v2 ?- V - !using["math","sys"];( G9 ]' m: ?, l5 J# X
- mvar:
- % y9 \2 w+ C7 ~! ^. ]! |8 _4 d) Q
- t=clock(),2 s& u, \$ v, Q9 U+ h% u
- oo{
- . c* a+ {& T) p\\" Q1 [. Q6 G: H: Q
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
- 6 a3 J! y5 F- c
- Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2)))))),0]
- 8 U$ l6 v/ w5 {1 P* z+ w
- };$ N\\" w# m5 s% x! J; R, q) C
- [clock()-t]/1000;
结果:$ [8 |, ]8 Q7 R% Q& s3 E8 Y6 N2 @
1008606.64947441
* A `( \- N& m7 N, z0.625 //时间
1 F" m4 w6 C; S7 r4 Y8 a+ N3 h" h9 u( l; C0 Y9 M2 C
或者这个,与上面效率差别不大:; |8 h7 M( M7 K# E( u% O& M4 q
 - !using["math","sys"];9 R6 V, b, H3 |; ^, o1 M
- mvar:
- % _8 r) D4 A4 Y3 ^1 q\\" S
- t=clock(),% A6 c$ l\\" G* v/ t
- oo{/ W& N! {3 X8 z. H6 A
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
- . C2 h3 o7 B: I2 [
- Sum[Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2))))))]]
- 7 S9 r( C: m* N/ @4 w- ?. E: l
- };1 y( p5 E1 H0 Z
- [clock()-t]/1000;
% ]: J+ N. i0 nForcal代码2:求和函数sum,非矢量化代码+ R& o. |; Y- o1 Z$ J$ R
- f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
! l$ A4 Q2 {0 G5 A\" T8 _ z) h - sum["f",0,1,0.0011,1,2,0.0009];
复制代码 结果:
9 `( k. }5 V" X2 R1008606.64947441! t6 H2 m! _3 a! A n. ~
0.719 //时间1 p8 z( a8 a! ~! p0 x& s s5 ~: E
" O" l9 N% c8 O0 e* B0 u4 aForcal代码3:while循环: z* G- ^* v5 f
- mvar:
9 D+ n: q$ `- a* T - t=sys::clock();
( B2 K3 S/ T, d6 M, t4 t% _6 a - s=0,x=0, : ]2 L4 d3 o/ \
- while{x<=1, //while循环算法; 6 N/ R( \0 |. `' w) i
- y=1,
\" Z1 Z3 E) E3 s q - while{y<=2, 4 q Q, {& H5 E6 w
- s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))),
; D( }7 K5 s# r - y=y+0.0009
6 u) E% v0 s# v/ v( A6 J - },
4 u; o\" D\" ]% r2 l3 M L\" ^8 y - x=x+0.0011 5 L' I+ X6 G3 x
- },
4 }& V& h\" E\" X/ Q - s;2 b% W# y/ p: S9 v, k
- [sys::clock()-t]/1000;
复制代码 结果:
; _& Q- w# X1 ]3 c1008606.64947441
( z6 n" j& b; k4 A$ m* r2 y0.734 //时间
$ V6 R! Y* V& r1 ?; Y, H
I4 \6 a& n( a$ x. m大家可下载OpenFC进行测试:http://www.forcal.net/xiazai/forcal9/openfc32w.rar
3 P2 D. e" e- c# o" E# {, q( F
2 v" }5 ~' Q3 r( O3 Z, b" j/ u( n9 ~注意Forcal的矢量化代码第一次运行有时效率较低。4 T# d, c2 O) u! C( i* |& X
1 z. p1 g8 y! `0 }例子1中Forcal和matlab都是矢量化代码,但matlab跑不过Forcal。该例子的特点是函数调用频繁,临时变量生成多,但矩阵很小,矩阵的各种函数运行时耗时较少。故说明Forcal函数调用+变量管理效率优于matlab。
' \) U8 ]0 T, u) I( R1 t0 \* \1 @1 G, U
例子2中Forcal的矢量化代码是最快的,但与matlab的矢量化代码相比仍有差距。该例子的特点是函数调用少,临时变量也少,但矩阵大。故说明Forcal的各种矩阵函数Sin、Cos及矩阵的加减运算等函数的内部设计不及matlab。3 s% l5 Y* x% {+ d
t0 q* A0 T" e& ]; B( h
如能在函数内部设计上下点功夫,例子2超越matlab也是可能的。在这方面,期待高手们的指点。
4 h! r3 V8 O2 ]! b
. h( H1 R% S9 w1 l \: c8 O: H如果例子2速度也超越了matlab ,matlab矢量化的神秘面纱就揭开了。6 O/ l+ u# N9 \, f9 u$ H
5 H# d- M6 t L. p- w顺便说一下,例子1如果用C++的运算符重载来实现,速度将比Forcal慢一些,也就是说,在涉及运算符重载时,脚本的效率有时比C++还要高些。8 \7 w6 C2 y3 [. N- b- H6 ]. o1 e l
|
|