- 在线时间
- 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 编辑
v; f5 X7 t( c) h# s
$ e1 x- e( u% P6 i) ?我正在练手设计的FcMath库也打算以矩阵运算为基础,设计一些专门的函数对数组元素集中运算,运行效率确实有所提高(甚至有些涉及矩阵的算法比matlab还快),代码也简洁了,但不知这是不是矢量化?& a2 \5 O+ W) @+ F3 N' u
$ W5 L( u% _$ {2 c5 [8 Z1 F脚本运行效率应该取决于函数调度效率、对象管理效率和函数内部算法的实现。
5 [& y4 t/ e& J! Y9 @" |, n s" f A1 E3 |, b9 i# U" Q4 J
我感觉,matlab的函数调度效率较低,对象管理效率这个不好说,但一些函数内部的设计比较优秀。故有些Forcal代码比matlab快,而有些慢。7 o' i& M. l( D6 v
! @/ b+ ]: f$ P* @. J以下例子体现了Forcal和matlab的效率差别所在。
0 l# c3 O! z& W& f0 ?' q( o
! b, K4 ^# i4 C+ `这个matlab程序段是网友lin2009 给出的,理论结果是每个元素均为275000。- clear all- B- l6 R& ]% p# T1 X
- clc7 [- b, \! s7 n+ |0 G
- tic. N8 Y; T' x- O9 @/ |' K
- k = zeros(5,5); % //生成5×5全0矩阵
5 q1 ?$ n6 f. w- Y k( ]\" ?' e - % 循环计算以下程序段1000 00次:$ S2 ^1 G- k. @/ I
- for m = 1:1000 003 P) z5 {2 j* b5 I0 a9 u
- a = rand(5,7);+ I2 x) i R\" t\" Z9 z
- b = rand(7,5);%//生成5×7矩阵a,7×5矩阵b,用0~1之间的随机数初始化) Z$ t: Z/ v. I4 t
- k = k + a * b + a(1:5, 2:6) * b(2:6, 1:5) - a(:, 7) * b(3, :);$ o/ E) i W6 d- |( ]
- end
: ?1 |$ w( L, K) A - k7 V; s! I* v0 |
- toc
复制代码
( M! R6 x/ Z% ^9 ^: jForcal代码1:运行稍快的代码,比matlab约快10%吧?
/ V- S. _, m. r5 A - !using["math","sys"];9 Z* n9 X! P0 l$ X! ~# Y
- mvar:
- 0 P( Z6 g* K* I) A3 c$ @8 T
- t0=clock(),+ `1 J/ Y& g, L7 ?; {2 K
- oo{k=zeros[5,5]},: g) r3 I1 l8 F7 T7 e4 t/ C8 X
- i=0,((i++)<100000).while{! I9 o: R% W' i
- oo{; b8 [8 _4 o: g( z\\" p
- a=rand[5,7], b=rand[7,5],
- + m5 r7 U9 t3 b' W
- 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)]
- ( P& O! A ~) P( H
- }
- ) ~ l) e* C. @! Z. J/ X/ U
- },$ l. O4 w3 D\\" K+ B; @) m- x3 H5 \
- k.outm(),( ~+ |+ t. u$ a\\" h F
- [clock()-t0]/1000;
在我的电脑上运行时间为3.344秒。
4 H+ I( ^2 K) b) I# \8 d8 |1 _5 {. S- x5 {
Forcal代码2:比较好看些的代码,似乎也比matlab稍快吧?$ J" Q ?6 n5 o1 o3 p: F7 j( i: h
 - !using["math","sys"];1 S' e7 @6 Z; r) d( W2 d
- (:t0,k,i,a,b)=
- 4 U& e! ?, S3 u$ l7 F
- {$ ~4 `2 _+ `# U; H5 X6 n
- t0=clock(), Q# `/ Q7 e( ?7 p4 J
- oo{k=zeros[5,5]},
- 4 m. ] ~1 ^\\" F- w( M9 f) F
- i=0,((i++)<100000).while{
- 2 S& n* T) h6 W7 _* k5 B
- oo{5 w8 T4 r1 l$ N
- a=rand[5,7], b=rand[7,5],* u( W) g% `% g1 ^+ L* L3 y
- k.=k+a*b+a(0,4:1,5)*b(1,5:0,4)-a(neg:6)*b(3:neg)! {7 W- n3 L3 q2 N8 H8 Z8 C) b2 W! S
- }* b$ ~# M8 w6 j! ?
- },! ?% k; x0 E6 m8 q6 m+ o
- k.outm(),
- . q\\" ]8 B# r- ~1 b
- [clock()-t0]/1000
- 4 d$ E, X' }6 z, o3 y\\" S4 e
- };
在我的电脑上运行时间为3.579秒。" X& t. d l% ~$ }& M
" A3 {. m- A$ a$ V
例子2:
* ?. {/ ?$ |# o$ C. b一段程序的Forcal实现:
" Z/ D! o+ p, G/ m- //用C++代码描述为:* e8 ~9 m3 l# x: X. T
- s=0.0; , P5 q/ X1 v$ q6 P# X9 g
- for(x=0.0;x<=1.0;x=x+0.0011) / ~6 N, c p5 b6 C$ V
- {
+ Y4 ~/ z3 ]' \+ y& ?* h( X b8 O - for(y=1.0;y<=2.0;y=y+0.0009)$ X* K0 u. w) C
- {$ V$ n1 F: j) n# n\" \% A; {9 }
- s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
5 F' i- @8 ?8 O( s - }0 x' Z3 ~0 s\" H* q: C9 E2 K
- }
复制代码 结果:
2 P- t( _$ H9 O1008606.64947441
5 U m! o. m% `: C: N0.609 //时间
) p1 _" Z1 @4 [! ?( D2 F u
6 R8 F8 Z& _1 B/ f- x这个matlab程序段是网友yycs001给出的。
) ]0 Z1 a, F" g% K. w- %file speedtest.m2 p0 U( X- u8 N' p: w* b
- function speedtest8 U; p, a6 q' \7 n\" ]
- format long
( c' m: Z6 d0 `+ B - tic
* I! ]9 R, c: t- Q+ Z - [x,y]=meshgrid(0:0.0011:1,1:0.0009:2);- l$ e: h3 X% i* i2 p$ E
- s=sum(sum(cos(1-sin(1.2*x.^(y/2)+cos(1-sin(1.2*y.^(x/2)))))))
/ \) h- m- K: P\" `; ]& _9 C4 f/ V - toc
复制代码 4 q4 t* q. e s/ o0 z
Forcal代码1:**数组求和函数Sum,完全矢量化的代码 Z* B* g- S' R' G' c( t& {
 - !using["math","sys"];
- ; J9 S/ c* H, p+ j7 L
- mvar:
- $ C) k! F/ V! B# e\\" \ R
- t=clock(),5 T) S0 m8 ~; b
- oo{
- 8 _& D& r$ I- k$ |& b
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],
- , T\\" I( \& J3 Q7 t) m
- Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2)))))),0]
- + P) X; R, O$ T# v9 w: H% r
- };7 g' a8 y6 g. ?: w, t
- [clock()-t]/1000;
结果:
; a! L" U: \) p) V1008606.64947441
/ ~. |% h1 B2 S# r0 G0.625 //时间
4 H7 Y$ D7 C, j
& g% M1 @0 T( {' y& B5 k( B- d或者这个,与上面效率差别不大:
& {2 [2 S& `/ _- h - !using["math","sys"];: H0 C+ I3 E/ v6 |& H, x
- mvar:
- 1 |6 _3 U\\" F% n& U6 j; z+ x% Q2 r
- t=clock(),& W9 \% S0 o3 m
- oo{! C1 Z! s! x* G. L; O9 |8 H
- ndgrid[linspacex(0,1,0.0011),linspacex(1,2,0.0009),&x,&y],: m# F6 |7 u5 n# H4 i\\" n) y: q
- Sum[Sum[Cos(rn(1)-Sin(rn(1.2)*x^(y/rn(2))+Cos(rn(1)-Sin(rn(1.2)*y^(x/rn(2))))))]]8 o& Q( \; h+ r& r4 S3 S
- };
- ' T% V. L/ S5 S\\" J
- [clock()-t]/1000;
+ o, D! H' k, r4 R/ IForcal代码2:求和函数sum,非矢量化代码
. ^4 c% z# |+ y1 O: [- f(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2)))));
0 H) G- T, y( ]1 M - sum["f",0,1,0.0011,1,2,0.0009];
复制代码 结果:/ v3 z, }3 Z( D4 Q
1008606.64947441& `$ i5 M0 d3 x4 p+ l9 A" a; \
0.719 //时间
S2 k3 p2 q" d& c9 ^+ d
, x' `0 a/ p6 s/ {Forcal代码3:while循环* {" `; T% X: F5 u8 m" t$ M
- mvar:4 J5 x9 K' a4 U$ j2 i% F8 c
- t=sys::clock();) ]0 V4 t/ @/ X9 y) I
- s=0,x=0,
; d8 m+ U4 r6 T2 m0 h# E - while{x<=1, //while循环算法;
- B y1 F/ q J+ w& C* l - y=1,
\" \( t* H# i& L ^) S - while{y<=2,
: `: q2 L3 t6 d - s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))), ) R9 s5 \. Q1 h% r
- y=y+0.0009
' x; k* }: q( \6 ]- T0 X2 V - }, 9 ?( ^) C% f! c8 V2 o\" @
- x=x+0.0011 . s8 @: m% K; f\" ?6 s& L$ Y& D0 N
- }, & E h4 m. n% }) q$ J
- s;2 l\" h1 M! ]; d; Q+ j
- [sys::clock()-t]/1000;
复制代码 结果:+ L' i- u" V% X7 a) d
1008606.64947441
" R! j. ]. `( p }9 b" {7 ^8 Z$ u0.734 //时间
5 T6 w9 o# Q7 M4 y3 F$ w9 h' z! {/ Z ?; I" w, k' R7 \$ {
大家可下载OpenFC进行测试:http://www.forcal.net/xiazai/forcal9/openfc32w.rar. D& F4 P$ r! Q+ N$ H
4 Z2 `& `) k* r$ y/ E1 O9 q注意Forcal的矢量化代码第一次运行有时效率较低。
. x- l& U: b- _+ X
1 f1 E# [$ N" o例子1中Forcal和matlab都是矢量化代码,但matlab跑不过Forcal。该例子的特点是函数调用频繁,临时变量生成多,但矩阵很小,矩阵的各种函数运行时耗时较少。故说明Forcal函数调用+变量管理效率优于matlab。
3 @ Y5 U% c& N' _% o, ]; _- _! S6 u
例子2中Forcal的矢量化代码是最快的,但与matlab的矢量化代码相比仍有差距。该例子的特点是函数调用少,临时变量也少,但矩阵大。故说明Forcal的各种矩阵函数Sin、Cos及矩阵的加减运算等函数的内部设计不及matlab。
9 C H7 V5 G8 W+ t; }* _! R' u- w6 g( p
如能在函数内部设计上下点功夫,例子2超越matlab也是可能的。在这方面,期待高手们的指点。
# Z' G, Y) n* @8 Z$ X. \
8 {5 G6 Q% W+ K- F' ]9 u. ?# u/ M如果例子2速度也超越了matlab ,matlab矢量化的神秘面纱就揭开了。7 f4 N. g& d* h1 U9 C
Y: E/ {( E- z9 a+ J1 ^顺便说一下,例子1如果用C++的运算符重载来实现,速度将比Forcal慢一些,也就是说,在涉及运算符重载时,脚本的效率有时比C++还要高些。
* A% c& ?# ]$ v |
|