2022年C++编码优化 .pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《2022年C++编码优化 .pdf》由会员分享,可在线阅读,更多相关《2022年C++编码优化 .pdf(15页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C+ 代码优化谈到优化,很多人都会直接想到汇编。难道优化只能在汇编层次吗?当然不是,C+层次一样可以作代码优化,其中有些常常是意想不到的。在 C+层次进行优化, 比在汇编层次优化具有更好的移植性,应该是优化中的首选做法。确定浮点型变量和表达式是 float 型为了让编译器产生更好的代码(比如说产生3DNow! 或 SSE 指令的代码 ), 必须确定浮点型变量和表达式是 float 型的。要特别注意的是,以 ;F; 或 ;f; 为后缀(比如:3.14f)的浮点常量才是 float 型,否则默认是 double 型。为了避免 float 型参数自动转化为 double,请在函数声明时使用 floa
2、t。使用 32 位的数据类型编译器有很多种,但它们都包含的典型的32 位类型是: int,signed,signed int,unsigned,unsigned int,long,signed long,long int ,signed long int ,unsigned long,unsigned long int 。尽量使用32 位的数据类型,因为它们比16 位的数据甚至8 位的数据更有效率。明智使用有符号整型变量在很多情况下, 你需要考虑整型变量是有符号还是无符号类型的。比如, 保存一个人的体重数据时不可能出现负数,所以不需要使用有符号类型。但是,如果是要保存温度数据,就必须使用到有符
3、号的变量。在许多地方,考虑是否使用有符号的变量是必要的。在一些情况下,有符号的运算比较快;但在一些情况下却相反。比如:整型到浮点转化时,使用大于16 位的有符号整型比较快。因为x86 构架中提供了从有符号整型转化到浮点型的指令,但没有提供从无符号整型转化到浮点的指令。看看编译器产生的汇编代码:不好的代码:编译前 编译后名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 15 页 - - - - - - - - - double x; mov foo + 4, 0 unsign
4、ed int i ; mov eax, i x = i ; mov foo, eax flid qword ptr foo fstp qword ptr x 上面的代码比较慢。不仅因为指令数目比较多,而且由于指令不能配对造成的FLID 指令被延迟执行。最好用以下代码代替:推荐的代码:编译前 编译后double x; fild dword ptr i int i; fstp qword ptr x x = i ;在整数运算中计算商和余数时,使用无符号类型比较快。以下这段典型的代码是编译器产生的 32 位整型数除以4 的代码:不好的代码编译前 编译后int i; mov eax, i i = i
5、/ 4 ; cdq and edx, 3 add eax, edx sar eax, 2 mov i, eax 推荐的代码编译前 编译后unsigned int i ; shr i, 2 i = i / 4 ;总结:无符号类型用于:除法和余数循环计数数组下标有符号类型用于:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 15 页 - - - - - - - - - 整型到浮点的转化while VS. for 在编程中,我们常常需要用到无限循环,常用的两种方法是while
6、(1) 和 for (; ;)。这两种方法效果完全一样,但那一种更好呢?然我们看看它们编译后的代码:编译前 编译后while (1) ; mov eax,1 test eax,eax je foo+23h jmp foo+18h 编译前 编译后for (; ;); jmp foo+23h 一目了然, for (; ;)指令少,不占用寄存器,而且没有判断跳转,比while (1) 好。使用数组型代替指针型使用指针会使编译器很难优化它。因为缺乏有效的指针代码优化的方法,编译器总是假设指针可以访问内存的任意地方,包括分配给其他变量的储存空间。所以为了编译器产生优化得更好的代码, 要避免在不必要的地方
7、使用指针。一个典型的例子是访问存放在数组中的数据。C+ 允许使用操作符 或指针来访问数组,使用数组型代码会让优化器减少产生不安全代码的可能性。比如,x0 和 x2 不可能是同一个内存地址,但 *p 和 *q 可能。强烈建议使用数组型,因为这样可能会有意料之外的性能提升。不好的代码typedef struct float x,y,z,w ; VERTEX ;typedef struct float m44 ;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 15 页 - -
8、- - - - - - - MATRIX;void XForm(float* res, const float* v, const float* m, int nNumVerts) float dp;int i;const VERTEX* vv = (VERTEX *)v;for (i = 0 ; i ;x * *m + ;dp += vv- ; y * *m + ;dp += vv- ; z * *m + ;dp += vv- ; w * *m + ;*res + = dp ; / 写入转换了的 x dp = vv- ;x * *m + ;dp += vv- ; y * *m + ;dp +
9、= vv- ; z * *m + ;dp += vv- ; w * *m + ;*res + = dp ; / 写入转换了的 y dp = vv- ;x * *m + ;dp += vv- ; y * *m + ;dp += vv- ; z * *m + ;dp += vv- ; w * *m + ;*res + = dp ; / 写入转换了的 z dp = vv- ;x * *m + ;dp += vv- ; y * *m + ;dp += vv- ; z * *m + ;dp += vv- ; w * *m + ;*res + = dp ; / 写入转换了的 w vv + ; / 下一个矢
10、量m -= 16; 推荐的代码typedef struct float x,y,z,w ; VERTEX ;typedef struct float m44 ; MATRIX;void XForm (float* res, const float* v, const float* m, int nNumVerts) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 15 页 - - - - - - - - - int i;const VERTEX* vv = (VERTEX
11、*)v;const MATRIX* mm = (MATRIX*)m ;VERTEX* rr = (VERTEX*)res;for (i = 0 ; i ;x = vv- ;x * mm- ;m00 + vv- ;y * mm- ;m01 + vv- ; z * mm- ;m02 + vv- ;w * mm- ;m03 ;rr-;y = vv- ;x * mm- ;m10 + vv- ;y * mm- ;m11 + vv- ; z * mm- ;m12 + vv- ;w * mm- ;m13 ;rr-;z = vv- ;x * mm- ;m20 + vv- ;y * mm- ;m21 + vv-
12、 ; z * mm- ;m22 + vv- ;w * mm- ;m23 ;rr-;w = vv- ; x * mm- ;m30 + vv- ;y * mm- ;m31 + vv- ; z * mm- ;m32 + vv- ;w * mm- ;m33 ; 注意 : 源代码的转化是与编译器的代码发生器相结合的。从源代码层次很难控制产生的机器码。依靠编译器和特殊的源代码,有可能指针型代码编译成的机器码比同等条件下的数组型代码运行速度更快。明智的做法是在源代码转化后检查性能是否真正提高了,再选择使用指针型还是数组型。充分分解小的循环要充分利用CPU 的指令缓存,就要充分分解小的循环。特别是当循环体本身
13、很小的时候,分解循环可以提高性能。BTW: 很多编译器并不能自动分解循环。不好的代码/ 3D 转化:把矢量 V 和 4x4 矩阵 M 相乘for (i = 0 ; i ; 4; i +) ri = 0 ;for (j = 0 ; j ; 4; j +) ri += Mji*Vj; 推荐的代码r0 = M00*V0 + M10*V1 + M20*V2 + M30*V3;r1 = M01*V0 + M11*V1 + M21*V2 + M31*V3;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - -
14、- 第 5 页,共 15 页 - - - - - - - - - r2 = M02*V0 + M12*V1 + M22*V2 + M32*V3;r3 = M03*V0 + M13*V1 + M23*V2 + M33*v3;避免没有必要的读写依赖当数据保存到内存时存在读写依赖,即数据必须在正确写入后才能再次读取。虽然AMD Athlon等 CPU 有加速读写依赖延迟的硬件,允许在要保存的数据被写入内存前读取出来,但是, 如果避免了读写依赖并把数据保存在内部寄存器中,速度会更快。在一段很长的又互相依赖的代码链中,避免读写依赖显得尤其重要。如果读写依赖发生在操作数组时,许多编译器不能自动优化代码以避
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年C+编码优化 2022 C+ 编码 优化
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内