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

本文整理了针对AMD64处理器的优化技巧,包括数组访问、循环展开、内存对齐、浮点运算优化等,旨在提升程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下内容整理自《Software Optimization Guide for AMD64 Processors》。转载请注明出处:http://blog.youkuaiyun.com/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


 

一、综合实战—使用极轴追踪方式绘制信号灯 实战目标:利用对象捕捉追踪和极轴追踪功能创建信号灯图形 技术要点:结合两种追踪方式实现精确绘图,适用于工程制图中需要精确定位的场景 1. 切换至AutoCAD 操作步骤: 启动AutoCAD 2016软件 打开随书光盘中的素材文件 确认工作空间为"草图与注释"模式 2. 绘图设置 1)草图设置对话框 打开方式:通过"工具→绘图设置"菜单命令 功能定位:该对话框包含捕捉、追踪等核心绘图辅助功能设置 2)对象捕捉设置 关键配置: 启用对象捕捉(F3快捷键) 启用对象捕捉追踪(F11快捷键) 勾选端点、中心、圆心、象限点等常用捕捉模式 追踪原理:命令执行时悬停光标可显示追踪矢量,再次悬停可停止追踪 3)极轴追踪设置 参数设置: 启用极轴追踪功能 设置角度增量为45度 确认后退出对话框 3. 绘制信号灯 1)绘制圆形 执行命令:"绘图→圆→圆心、半径"命令 绘制过程: 使用对象捕捉追踪定位矩形中心作为圆心 输入半径值30并按Enter确认 通过象限点捕捉确保圆形位置准确 2)绘制直线 操作要点: 选择"绘图→直线"命令 捕捉矩形上边中点作为起点 捕捉圆的上象限点作为终点 按Enter结束当前直线命令 重复技巧: 按Enter可重复最近使用的直线命令 通过圆心捕捉和极轴追踪绘制放射状直线 最终形成完整的信号灯指示图案 3)完成绘制 验证要点: 检查所有直线是否准确连接圆心和象限点 确认极轴追踪的45度增量是否体现 保存绘图文件(快捷键Ctrl+S)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值