C++性能优化笔记-7-编译器中的优化-2-不同编译器的对比

编译器中的优化

不同编译器的对比

下表对比了不同的编译器的优化效果。
必须强调的是,编译器在不同的测试例子上可能表现不同。下表仅供参考。

优化方法GnuClangMicrosoftIntel
通用优化
函数内联xxxx
常量折叠xxxx
常量传播xxxx
循环的常量传播xx--
指针消除xxxx
公共子表达式消除xxxx
寄存器变量xxxx
Fused multiply and addxxxx
生命周期分析xxxx
合并相同的分支xxxx
消除跳转xxxx
尾调用xxxx
移除总为false的分支xxxx
循环展开,数组循环xxxx
循环展开,结构体xxx-
相同循环体代码移动xxxx
数组元素的归纳变量xxxx
整数表达式的归纳变量-x1x
浮点表达式的归纳变量---x
乘法累加器,整数-xx-
乘法累加器,浮点-xx-
去虚拟化xxxx
Profile-guided optimizationxxxx
全局程序优化xxxx
整数代数化简
a+b = b+a, a*b = b*a (交换律)xxxx
(a+b)+c = a+(b+c), (a*b)*c = a*(b*c) (结合律)-xx-
a*b + a*c = a*(b+c)(分配律)xxxx
a+b+c+d = (a+b)+(c+d) (提高并行)---x
a*b*c*d = (a*b)*(c*d) (提高并行)-x-x
x*x*x*x*x*x*x*x = (((x2)2)2)xx-x
a+a+a+a = a*4xxxx
a*x*x*x + b*x*x + c*x + d = ((a*x+b)*x+c)*x + dxxxx
-(-a) = axxxx
a-(-b) = a+bxxxx
a-a = 0xxxx
a+0 = axxxx
a*0 = 0xxxx
a*1 = axxxx
(-a)*(-b) = a*bxxxx
a/a = 1xxx-
a/1 = axxxx
0/a = 0xxx-
乘以常量= 移位和加法xxxx
除以常量 = 乘法和移位xxxx
除以2的次幂 = 移位xxxx
(-a == -b) = (a == b)xxx-
(a+c == b+c) = (a==b)-xxx
!(a < b) = (a >= b)xxxx
(a<b && b<c && a<c) == (a<b && b<c)x---
浮点代数化简
a+b = b+a, a*b = b*a (交换律)xxxx
(a+b)+c = a+(b+c)(结合律)xx-x
,(a*b)*c = a*(b*c) (结合律)xx--
a*b + a*c = a*(b+c)(分配律)xxxx
a+b+c+d = (a+b)+(c+d), a*b*c*d = (a*b)*(c*d)xx--
a*x*x*x + b*x*x + c*x + d = ((a*x+b)*x+c)*x + dxxxx
x*x*x*x*x*x*x*x = (((x2)2)2)xx--
a+a+a+a = a*4xxx-
-(-a) = axxxx
a-(-b) = a+bxxxx
a-a = 0xxxx
a+0 = axxxx
a*0 = 0xxxx
a*1 = axxxx
(-a)*(-b) = a*bxxxx
a/a = 1xx--
a/1 = axxxx
0/a = 0xxx-
(-a == -b) = (a == b)xx--
(-a > -b) = (a < b)xxx-
除以常量 = 乘以倒数xxxx
布尔代数化简
没有分支的布尔操作xx-极少
a && b = b && a, a||b = b||a (交换律)xx-x
a && b && c = a && (b && c) (结合律)---x
(a&&b)||(a&&c) = a&&(b||c) (分配律)xx--
(a||b)&&(a||c) = a||(b&&c) (分配律)xx--
!(!a) = axxxx
!a && !b = !(a || b) (德摩根定律)xx--
a && !a = false, a || !a = truexxxx
a && true = a, a || false = axxxx
a && false = false, a || true = truexxxx
a && a = axxxx
(a&&b) || (a&&!b) = ax-xx
(a&&b) || (!a&&c) = a ? b : c-x--
(a&&b) || (!a&&c) || (b&&c) = a ? b : cx-xx
(a&&b) || (a&&b&&c) = a&&bxxxx
(a&&!b) || (!a&&b) = a XOR bxx--
向量寄存器中的位操作代数化简:
a & b = b & a, a|b = b|a (交换律)xx--
a & b & c = a & (b & c) (结合律)xx--
(a&b)|(a&c) = a&(b|c) (分配律)xx--
(a|b)&(a|c) = a|(b&c) (分配律)xx--
三值逻辑指令---x
(a) = axx--
~a & ~b = ~(a | b)xx--
a & ~a = false, a | ~a = truexx--
a & true = a, a | false = axx--
a & false = falsexxxx
, a | true = truexxx-
a & a = a, a | a = axx-x
(a&b) | (a&~b) = axx--
(a&b) | (~a&c) = a ? b : cx---
(a&b) | (~a&c) | (b&c) = a ? b : c----
(a&b) | (a&b&c) = a&bxx--
(a&&~b) | (~a&b) = a ^ bxx--
~a ^ ~b = a ^ bxx--
a <<b<<c = a<<(b+c)----
整数向量代数化简:
a+b = b+a, a*b = b*a (交换律)xx--
(a+b)+c = a+(b+c), (a*b)*c = a*(b*c) (结合律)xx--
a*b + a*c = a*(b+c)(分配律)xx--
a+b+c+d = (a+b)+(c+d)----
x*x*x*x*x*x*x*x = (((x2)2)2)xx--
a+a+a+a = a*4-x--
a*x*x*x + b*x*x + c*x + d = ((a*x+b)*x+c)*x + dxx--
-(-a) = axx--
a-(-b) = a+bxx--
a-a = 0xx-x
a+0 = axx--
a*0 = 0xx-x
a*1 = axx--
(-a)*(-b) = a*bxx--
乘以2的次幂 = 移位xxxx
(-a == -b) = (a == b)-x--
(a+c == b+c) = (a == b)-x--
!(a < b) = (a >= b)----
(a<b && b<c && a<c) == (a<b && b<c)----
浮点向量代数化简:
a+b = b+a, a*b = b*a (交换律)xx-x
(a+b)+c = a+(b+c), (a*b)*c = a*(b*c)(结合律)xx--
a*b + a*c = a*(b+c)(分配律)xx--
a+b+c+d = (a+b)+(c+d)----
x*x*x*x*x*x*x*x = (((x2)2)2)xx--
a+a+a+a = a*4-x-2*a+a+a
a*x*x*x + b*x*x + c*x + d = ((a*x+b)*x+c)*x + dxx-x
-(-a) = axx--
a-(-b) = a+b----
a-a = 0xx-x
a+0 = axxxx
a*0 = 0xx-x
a*1 = axx-x
(-a)*(-b) = a*b----
a/a = 1xx--
a/1 = a-x--
0/a = 0xx--
除以常量 = 乘以倒数----
(-a == -b) = (a == b)----
!(a < b) = (a >= b)----
通用向量优化:
自动向量化xx256bitx
合并广播到指令-x-x
merge blend into masked instructionxx-x
merge conditional zero into masked instructionx--x
合并布尔AND到掩码比较xx-x
消除所有为true的掩码xxxx
消除所有为false的掩码xx-x
表8.1. 不同C++编译器里优化的比较

测试在打开所有相关优化选项时编译在64-bit Windows下的测试代码,包括放宽浮点精度。测试了以下编译器版本:
Gnu C++ v.7.4.0 (2019, Cygwin64).
Clang C++ v.5.0.1(2019, Cygwin64).
Microsoft C++ Compiler v.19.21.27702 (Visual Studio 2019).
Intel C++ Compiler v.19.0.4.245 for Intel64, 2019.

Clang和Gnu编译器是在测试中表现最好的;Microsoft编译器在向量方面表现普通。在自动向量化方面,当前的Microsoft编译器使用256-bit向量而不是512-bit向量。Intel编译器自动使用512-bit向量,但需要指定/Qopt-zmm-usage:high
Clang编译器倾向于过多的展开循环。过多的循环展开会减慢性能,因为它会填满CPU中的微指令缓存或回环缓冲。

欢迎交流
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值