Visual Studio 2010中Visual C++代码生成

你好,我是十TZEN,是Visual C++编译器代码生成团队的编译器架构师。今天,我将介绍VisualStudio2010中一些值得注意的改进。

null

更快的LTCG编译 :  LTCG(链路时间代码生成) 允许编译器使用程序中所有模块的信息执行更好的优化(有关更多详细信息,请参阅) ee公司 在这里 ).  为了合并来自所有模块的信息,LTCG编译通常比非LTCG编译花费更长的时间,尤其是对于大型应用程序。  在VS2010中,我们改进了信息合并过程,显著加快了LTCG的编译速度。microsoftsqlserver(一个.text大小大于50MB的应用程序)的LTCG构建速度提高了约30%。

更快的Pogo仪器运行 :  概要文件引导优化(Profile-Guided Optimization,PGO)是一种优化方法,编译器使用概要文件信息为程序做出更好的优化决策。 看到了吗 在这里 在这里 介绍PGO。  PGO的一个主要缺点是,插入指令的运行通常比常规优化运行慢几倍。  在VS2010中,我们 支持插入指令的二进制文件的无锁版本。  这样的话,场景(PGI)的运行速度就快了1.7倍。

X64目标的代码大小缩减: 代码大小是影响性能的关键因素,特别是对于对指令缓存或工作集的行为敏感的应用程序。  在VS2010中,针对X64体系结构引入或改进了一些有效的优化。一些改进如下:

· 更积极地使用RBP作为帧指针来访问局部变量。RBP相对地址模式比RSP相对地址模式短一个字节。

· 使用C++ EH或Windows SEH启用尾部合并优化(参见 在这里 在这里 对于EH或SEH)。

· 将连续的常量存储合并到一个存储。

· 了解更多我们可以为64位立即数常量发出32位指令的情况。

· 了解更多可以使用32位移动而不是64位移动的情况。

· 优化C++ EH析构函数小函数的代码序列。

总之,我们观察到各种Microsoft产品(如Windows内核组件、SQL、Excel等)的代码大小减少了3%到10%。

“速度”的改进: 和往常一样,在不同的代码生成区域中也有许多代码质量调优和改进,以提高“速度”。  在这个版本中,我们关注更多关于X64目标的信息。  以下是 促成这些改进的一些重要变化:

· 在更多的情况下识别并使用CMOV指令

· 更有效地结合感应变量以降低寄存器压力

· 改进回路中强度折减区域常数的检测

· 改进循环中的标量替换优化

· 避免货代失速的改进方法

· 将XMM寄存器用于memcpy内部

· 改进内联启发式,以确定并做出更有益的内联决策

总的来说,我们看到一个8%%i 通过整数基准测试和X64浮点套件上的几个%%点测量的改进。

为X86和X64目标生成更好的SIMD代码 :  SSE/SSE2 SIMD代码的质量对游戏、音频、视频和图形开发人员至关重要。  与内联asm不同,内联asm禁止编译器对周围代码进行优化,而intrinsic的设计允许更有效的优化,并且仍然允许开发人员访问机器的低级控制。  在VS2010中,我们添加了几个简单但有效的优化,重点是SIMD内在质量和性能。  一些改进如下:

· 断开假相关性:  标量转换指令(CVTSI2SD、CVTSI2SS、CVTSS2SD或CVTSD2SS)不修改目标寄存器的高位。这会导致错误的依赖关系,这可能会显著影响性能。为了打破内存到寄存器转换的错误依赖性,VS2010编译器插入MOVD/MOVSS/MOVSD将高位置零,并使用相应的压缩转换。  例如,

cvtsi2ss xmm0,内存操作数 à movd xmm0,内存操作数 cvtdq2ps xmm0、xmm0

对于寄存器到寄存器的转换,插入XORPS以打破假依赖关系。

cvtsd2ss xmm1、xmm0 à xorps xmm1,xmm1                                             cvtsd2ss xmm1、xmm0

尽管这种优化可能会增加代码大小,但我们观察到,在一些实际的代码和基准程序上,性能有了显著的积极改善。

· 为常量向量初始化执行向量化:在VS2008中,一个简单的初始化语句,如 __m128 x={1,2,3,4}, 需要10个指令。与 VS2010,它被优化为几个指令。  这也适用于维度初始化。  为初始化语句生成的指令,如 __m128 x[]={{1,2,3,4},{5,6}}或{m128 t2[][2]={{1,2},{3,4,5},{6},{7,8,9}}; VS2010大大减少了。

· 优化uu mmu set u**()、 uu mmu setr u**()和uu mmu set1 u**()内在族。  在VS2008中,一系列解包指令用于组合标量值。当所有参数都是常量时,这可以通过单个向量指令实现。  例如,单语句, 返回mm设置16(0,1,2,3,-4,-5,6,7) ,需要大约20条指令才能在以前的版本中实现,而在以前的版本中只需要一条指令  VS2010年。

为XMM寄存器提供更好的寄存器分配,从而消除了许多冗余的加载、存储和移动。

· 为SSE比较启用比较和JCC CSE(公共子表达式消除)。  例如,下面左边的代码序列将优化为右边的代码序列:

ECX,CC1=PCMPISTRI                                  ECX,CC1=PCMPISTRI JCC(等式)CC1                                                      JCC(等式)CC1 ECX,CC2=PCMPISTRI à JCC(ULT)CC2公司 JCC(ULT)CC2公司                                                    JCC(P)CC3公司 ECX,CC3=PCMPISTRI JCC(P)CC3公司

支持Intel和AMD处理器中的AVX: Intel AVX(Intel Advanced Vector Extensions)是SSE的256位指令集扩展,专为浮点密集型应用程序设计(请参阅) 在这里 在这里 英特尔和AMD的详细信息)。  在VS2010版本中,所有AVX特性和指令都通过内部和外部接口得到完全支持/arch:AVX.  为了提高AVX代码生成的代码质量,已经添加了许多优化,在即将发布的博客文章中将详细介绍这些优化。 除了编译器中的AVX支持外,VS2010中的Microsoft宏汇编程序(MASM)还支持用于x86和x64的Intel AVX指令集。

使用/fp:fast进行更精确的浮点计算: 为了获得最大的速度,编译器可以在以下条件下积极地优化浮点计算 /fp:快速选项 .  结果是浮点计算错误会累积,结果可能会非常不准确,从而严重影响程序的结果。  例如,我们观察到浮点基准测试套件中有一半以上的程序在VS2008的X64目标上使用/fp:fast失败。  为了使/fp:fast更有用,我们在VS2010中对一些优化进行了“下调”。此更改可能会略微影响以前使用/fp:fast构建的某些程序的性能,但会提高其准确性。  如果您的程序在早期版本中使用/fp:fast失败,那么您可能会在VS2010中看到更好的结果。

结论 VisualC++团队关心的是使用编译器构建的应用程序的性能,我们继续与客户和CPU供应商合作来改进代码生成。如果您发现问题或改进机会,请告知我们 连接 或者通过我们的博客。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享