TA的每日心情 | 怒 2019-11-20 15:16 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 taoyulon 于 2024-7-31 18:00 编辑
?6 P0 y3 _9 w; k- n5 r- h" Q" s1 l2 B7 \. b- k: b
9 m2 h# h2 U5 K) ~3 X3 i( p
/ ^7 g+ a) N5 t; B( Q6 d$ FLinux 程序设计的一些优化措施- @9 X9 B! f2 Q+ F6 _) x
% X2 x4 A8 v3 x7 \: F5 Z
这些知识是在平常的阅读中,零散的获得的,自己总结了一下,分享在这里' S. p; l5 u' [
1 P8 T( _) Y8 C; Y2 d$ c, @6 Y全局变量VS函数参数) K* | l4 |7 _: i3 A, R. c% K
0 F5 \6 @, ?* U5 m, b( a: q$ G
全局变量在Linux下的驱动编程里边,用的是非常多,例如中断服务函数ISR,基本上都可以用全局变量来作为数据的更新,及事件的触发。给函数传递参数的效率一般来说,要低于直接使用全局变量,尤其是参数的数目太多的时候。参数传递,是需要先将参数push到stack中,等程序运行完毕,再从stack中pull出来,过程上要比global variable复杂。但是,全局变量过多的话,这里边就设计到管理的问题了,到后面就很难去控制这些变量的修改,这对于函数的模块化有不利的影响。
7 n; O3 f4 d, {2 w( r2 y' ^& b$ w3 ]! y$ }/ y! J
i=i+1;
5 }) c2 ~/ [) T4 ^4 Si++;! S+ E5 b C( p6 Y0 R6 _
i--;! h% N, q# j3 o6 @
这三个语句都通常引用在for()或者是while()里边,从执行效率上来说 3》2》1
* ~6 F1 R6 Z8 p d这和最终生成的汇编语言有关,一般来说,影响不会太夸张。
/ B9 a) W( Y2 r3 W) G
! a' P9 N$ Y! d! r$ O$ sswitch-case语句
* A' w/ A: J. M8 h t# V
) {9 h1 `# U" k/ Hswitch-case语句,也是用的非常多的语句。3 y) Y1 w( x4 T W4 J1 u$ j2 T
这里首先的优化原则就是:将发生概率最高的条件,放在最先判断的位置。这样就能够有效的降低
. K5 |3 e2 K& _5 `/ Q# e1 c! B比较的次数,达到更优的效果。或者,有一种更好的方法来替代switch-case语句的方法,就是利用查表
$ \% |0 R3 R# x/ M* p比如
, g w5 B5 ]. g7 N" m. w# \6 d; Bswitch(msg_type)
; `$ C6 i2 l' B{
' C- n5 _' g& u' R3 s/ {$ M J7 mcase DATA:
E( ?6 Z' ^: J: | G6 H( x3 \ handle_data_fun();
1 i0 z7 N' }* V/ s# |8 i2 u break;
. z; q+ \: C( `: `5 W5 t7 o+ h( lcase RTS:: k" V9 j, e# e# R( q5 o' L' `
handle_rts_fun();9 }- W( |0 P5 Z# W3 N
break; & C) S8 E( F, Z; `6 N
........ x6 j5 }9 t; Z0 w+ H0 y! z
}
2 Y3 {4 f. F- c# T这里就可以用函数指针和查表的方式,获得handle_fun的方法来替代。9 z- W) b8 T; {) `" M5 T* ]) }
2 N s0 y; @$ d
处理函数都在初始化的过程中,放到*handle_fun[MAX]相应的位置上* P9 U$ Y! l4 G- a3 ]
int (*handle_fun[MAX])(struct msg_t *msg);
4 r" \; a4 L* Q9 }int msg_type = msg->type;+ s/ S$ |, R+ P
handle_fun[msg_type](msg);//即可; t" X' E) v( o4 U% r8 w
这种方法,在Linux的网络协议里边,用的非常多,一般对应的查表方式为hash表结构。/ ^! p# v& \, }3 x/ P$ [
! ~0 n* e/ W; D& W( v8 b6 psturct 和 union的使用, `$ ~! |, x' z7 n/ W
" D, d9 V6 ^) Q1 C
sturcut 使用,一定要考虑到字节对其的问题,struct中,不同的安排顺序,sizeof是不同的所以要调整好位置,尽量保证struct的size最小。; d* j: q4 r" D+ V" e' W1 g3 x
7 O9 H( V; n4 x! V# t% Junion的使用,比如对不同包的数据结构上,是不一样的,所以尽量使用union来区分不同的包结构这样对程序的可读性比较好。8 n* Y9 Q0 J+ X: P5 V- v: R% w
# e! | H$ k6 s
volatile的使用. P6 Y) P4 E; @* X2 [
3 i L+ \7 ]6 f3 i7 v( F' {' l4 F0 V/ q' L这在驱动编程方面是非常有用的一个标志。目的是不让编译器compiler把当前的变量优化掉。尤其是涉及到硬件寄存器的值的时候。
. d, R2 K# R5 k2 P/ Y! a* R8 c0 U+ S
乘除运算的简化: f6 u6 }; y# l( u& {" Y
0 {; ~( t1 ^6 Y6 t6 F乘除运算,对ARM来说太致命,arm的乘除都生成一堆的汇编指令才能完成。所以一般可以通过位操作,比如移位,取低位来进行适当的化简。比如 a*8 = a<<3;
" z3 ]( K! c; K9 l' c1 n( [/ Z. |# z3 S. `, c' Q' y( W
Inline 函数
' {/ O& y( ^8 `" k在实现比较简单功能的函数,以及那些调用非常平凡的函数,都可以在函数前加入inline的标识。这样在产生汇编的时候,能够更有效。也可以替代较复杂的define语句。
) P- ?1 r3 ?( a* t! j1 T Z
3 Z( O+ R" t5 p, w' k6 \* |: U
9 v8 K1 w& ]7 n' e/ x* P$ A/ P4 j; J; V/ c6 u
9 A, w- F5 w: h: `, H. n9 G& I/ ]0 n- O7 W, [# N' d
|
|