amd64软件优化学习笔记(未完待续)

以下内容整理自《Software Optimization Guide for AMD64 Processors》。转载请注明出处:http://blog.csdn.net/qingheuestc, by EinsteinInIct。

 

1,在单精度浮点变量后面加上f,可以显示的通知编译器不把单精度当多双精度来处理。(除非内存非常紧张,否则最好不要用)

2,当用数组模式进行访问时,使用数组名比使用指针能够给编译器提供更多的信息进行优化。当然有的时候并非如此,因此要通过test来看哪种方法更合适。

3,对于一些长度确定的短小的循环,考虑将其展开。不但可以减小分支预测等的开销,而且可以充分利用register进行优化,消除数据依赖性等。

4,在符合分支条件中,选择合适的表达式顺序以充分利用short circuit特性。(需要严密的测试性能差异)

5,If语句中,考虑两点:

a)逻辑表达式的短路特性

b)将经常发生的事情放在附近

6,动态内存分配时,注意对地址进行对齐。

7,在循环中,利用register来避免不必要的store-to-load开销(解除raw依赖)。

8,匹配store和load size(??)

9,在没有连续或者近似连续的case的地方,用if,else来替代switch。另外,在switch中,按照可能性的顺序从高到低排列case,可以减小分支比较的次数。

10,使用函数原型,对于static的函数加上static修饰符,有时可以给编译器提供更多的信息以供优化。

11,养成使用const修饰符的习惯,不但可以是代码更加robust,而且可以方便编译器进行优化。对于使用的数据,修饰信息越多,对于代码的理解越到位,也更加方便进行优化。

12,消除循环中的不变量,不仅是数据,也包括控制流。从最内层循环一直往外进行优化。

13,利用循环展开等方法尽量让流水线,寄存器等更加饱满,以充分利用宝贵资源。

14,将大的表达式拆分成小的表达式以避免重复计算,因为ansi中的一些标准禁止编译器进行拆分。

15,对于结构体中的变量的声明,按照size从大到小的顺序排列并进行padding,这样,他们就能够很好的对齐(??)。而且结构体的数组也能够很好的对齐。对于局部变量的声明,也按照从大到小的顺序进行定义。

16,当一个表达式中有多个整数除法时,以乘代除,提高速度。

17,避免在一个函数内部频繁的对指针进行解引用。因为指针可能存在别名的问题,编译器不敢贸然进行优化。这样,频繁的解引用有可能造成访存量增加而成为瓶颈。如果必要,可以在函数开头将指针指向的内容拷贝到局部变量中来,这样或许会充分利用register。

18,对于数组的索引,使用ptrdiff_t不但可以提高可移植性,而且通常会得到更好的性能。

19,考虑整数操作数的符号对性能的影响,选择合适的数据类型。Amd64中,signed integer 到float的转换比unsigned integer到float的转换更快。

a) Unsigned types

  i. Division and remainders

 ii. Loop counters

iii. Array indexing

b) Signed types

  i. Integer to floating pointconversion

20,加速浮点除和开方运算

  如果应用中有大量浮点除或者开方运算,可以考虑通过inline汇编用sse指令或3Dnow来实现,或者是用支持sse和3Dnow的编译器。亦或者通过设置X87的精度来提高速度。

21,对于32位的浮点到整数转换,有专门的3Dnow指令PF2ID来实现。对于double to int,可以用以下方法:#define DOUBLE2INT(i, d) \

{double t = ((d) +6755399441055744.0); i = *((int *)(&t));}

double x;

int i;

DOUBLE2INT(i,x);

22,

When using ld, include the followingcommand line option:

-Bsymbolic

If using gcc to build a library, add this option to the command-line:

-Wl,-Bsymbolic

 

Key Optimization

1,避免内存尺寸的不匹配(比如写两个4字节的连续内存,然后读开始地址的8字节数据抑或相反),应该让读和写的尺寸都一样大。这样方便进行forwarding,否则此时的延迟是非常大的。因为不但要写,还要读。解决方案是利用cpu中已有的指令和存储单元(register),保证数据读写尺寸的一致性。

2,保证数据对象是自然对齐(地址是尺寸的倍数)的(很重要)。

3,对于一个快速通用的内存拷贝,调用ms或者gcc工具提供的memcpy(),该函数对各种blocksize和alignment都做了优化。对于小的数据块,使用inline汇编:load,load,store,store


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值