也谈“C++编译器到底能帮我们把代码优化到什么程度?”

涉及到这个帖子:http://topic.csdn.net/u/20120405/10/815acda1-0e12-4b7d-aa89-1d2f68a60704.html
由于较早前另一个雷同帖子:http://topic.csdn.net/u/20120102/01/fc8d7aa4-bffc-4d9a-a34a-5056c6d27b54.html 的作者hengyunabc对其原创性有异议(第一个帖子68楼),所以另开一帖。

这篇文章写得不错,但是也存在一些问题,其一是论述过程有错误:

[Quote=引用 hengyunabc 的回复:]
下面来看下编译器生成的结果(vs2010,release):

01. for(int i = 0;i < SIZE; i++) {
02. S += a[i];
03.013B1040 mov ebx,dword ptr [eax+4] //把a[0],a[4],a[8]...累加到ebx中
04.013B1043 add ecx,dword ptr [eax-8] //把a[1],a[5],a[9]...累加到ecx中
05.013B1046 add edx,dword ptr [eax-4] //把a[2],a[6],a[10]...累加到edx中
06.013B1049 add esi,dword ptr [eax] //把a[3],a[7],a[11]...累加到esi中
07.013B104B add dword ptr [ebp-4],ebx
08.013B104E add eax,10h
09.013B1051 dec dword ptr [ebp-8]
10.013B1054 jne main+40h (13B1040h)
11. }
12. cout<<S<<endl;
13.013B1056 mov eax,dword ptr [ebp-4]
14.013B1059 add eax,esi
15.013B105B add eax,edx
16.013B105D mov edx,dword ptr [__imp_std::endl (13B204Ch)]
17.013B1063 add ecx,eax //上面的3条add指令把ebx,ecx,edx,edi都加到ecx中,即ecx是累加结果

可见编译器生成的代码是最好的代码,消灭了中间变量i,减少了循环次数,消灭了会造成CPU不能乱序执行的因素。
[/Quote]

显然,vs2010生成的代码并没有“消灭了中间变量i”。另外,代码编译成这样,主要目标是提高超标量架构的指令并行度,而非乱序执行,虽然代码3~6行确实可以看出对乱序执行的考虑(利用cache的预取特性)。
...全文
1030 49 打赏 收藏 转发到动态 举报
写回复
用AI写文章
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 48 楼 yajiedesign 的回复:
用vs2013测试.开sse2, 0.960s,开avx0.874s.差距已经比较小了.看了汇编,自动使用了高级指令集.看来人类的优势保持不了多久啊.
才注意到您的回复。我特意装了个VS 2013测试了一下,使用/arch:sse2|avx确实有进步,已经很接近手工代码,看来vc++ 2013的优化能力差不多达到了两年前intel C++ XE的水平。
yajiedesign 2014-06-28
  • 打赏
  • 举报
回复
用vs2013测试.开sse2, 0.960s,开avx0.874s.差距已经比较小了.看了汇编,自动使用了高级指令集.看来人类的优势保持不了多久啊.
liuyun885 2012-11-24
  • 打赏
  • 举报
回复
这么快就完了,我还没看够呢。。。
冷月孤城 2012-05-04
  • 打赏
  • 举报
回复
很艰难的看完了。
CandPointer 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 的回复:]

引用 39 楼 的回复:其实vc2010编译代码的性能,比gcc和bcc还是有优势的,只能说icc太强了,都是什么人在做icc编译器呀?:)ICC有那么强大么?就我平常的经验来说,对于常规应用,多数情况下,vc和icc以及gcc是基本打平手的,而且多数情况下,vc以及新版gcc优化得更好一点.对于大规模的矩阵运算,icc有一定的优势,并且icc的数学库是优化过的,性能会好一点.但icc编译的速……
[/Quote]

intel 的mkl,ipp 都是很性能强的库

编译慢的话,有个选项,可以并行编译。能快点。当然,如果选了 ipo优化,编译速度会慢很多,因为每个源码要编译两次
  • 打赏
  • 举报
回复
还真有这么优化性能的,SGI的RASC工作站就集成了大规模FPGA,软件可以在运行时编程出自己需要的特定硬件,然后在这个硬件上运行定制的软件以优化性能。
jiandingzhe 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 的回复:]

应用层优化,算法优化和汇编指令优化到头了的话,还可以微代码优化,指令流水线优化,CPU内部Cache优化,IC电路优化……
[/Quote]
干脆用FPGA把函数写在里面好了……
  • 打赏
  • 举报
回复
就这个例子:
int Sum_CPP(int *a, int size)
{
int s = 0;
for(int i = 0; i < size; ++i) s += a[i];

return s;
}

icc优化确实比VC强了不是一点半点,是2倍还多的关系。见CandPointer的测试结果。
如果不开SSE优化的话,VC有可能和icc差不多。

redleaves 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 的回复:]其实vc2010编译代码的性能,比gcc和bcc还是有优势的,只能说icc太强了,都是什么人在做icc编译器呀?:)[/Quote]ICC有那么强大么?就我平常的经验来说,对于常规应用,多数情况下,vc和icc以及gcc是基本打平手的,而且多数情况下,vc以及新版gcc优化得更好一点.对于大规模的矩阵运算,icc有一定的优势,并且icc的数学库是优化过的,性能会好一点.但icc编译的速度和生成代码的尺寸就有点吓人了...
赵4老师 2012-05-03
  • 打赏
  • 举报
回复
应用层优化,算法优化和汇编指令优化到头了的话,还可以微代码优化,指令流水线优化,CPU内部Cache优化,IC电路优化……
  • 打赏
  • 举报
回复
其实vc2010编译代码的性能,比gcc和bcc还是有优势的,只能说icc太强了,都是什么人在做icc编译器呀?:)
CandPointer 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 的回复:]

多谢你的测试,看来icc的自动SSE矢量化能力是很强的,VC2010即便强制/arch:SSE2也根本没生成SSE代码。
至于测量时间的差别,可能需要增大循环次数才能比较可靠,执行时间太短的话,可能每个函数执行过程中碰到的线程切换次数不同,多一次少一次就有几十ms的误差,另外clock()的精度也有限。
[/Quote]

现在更新了 intel parallel studio 的补丁,编译选项不太熟悉了。
以前,老版本的, 有个 很常用的, qvec + qvec-report , 自动报告提示数据依赖等,指导用户 手工把代码写成 sse。
还有 vtune, 提示 cache 命中率 之类的。

你这样的汇编高手, 若配合 icc 的 report, 定能够写出性能上 登峰造极 的代码。


昨晚试了下,zyl910的VC6、VC2010、C#2010、VB6和MMX、SSE指令集 运算性能大比拼(
http://topic.csdn.net/u/20120413/17/d0f0dd3f-ca55-41f6-9fa0-321a85be5668.html

其中,有个
f1_min[1]: 274
f1_min[2]: 274
f1_min[3]: 271
这是 intel 的

而vc2010 的
f1_min[1]: 1553
f1_min[2]: 1575
f1_min[3]: 1554

数值越小越好。 vc和intel,搞出了数量级的差别,

据说 pgi的编译器更强,面向超算hpc的
  • 打赏
  • 举报
回复
多谢你的测试,看来icc的自动SSE矢量化能力是很强的,VC2010即便强制/arch:SSE2也根本没生成SSE代码。
至于测量时间的差别,可能需要增大循环次数才能比较可靠,执行时间太短的话,可能每个函数执行过程中碰到的线程切换次数不同,多一次少一次就有几十ms的误差,另外clock()的精度也有限。
CandPointer 2012-05-02
  • 打赏
  • 举报
回复
更新了编译器补丁,好像少了个 qvec 自动矢量化的选项...
以往,使用 qvec + vec-report, 会自动报告 哪些代码需要用户手工调整,以便 sse矢量化

intel 编译器,对 sum2 (asm ssse3) 的编译结果,反而比 vc2010编译出来的还慢了。


CandPointer 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
涉及到这个帖子:http://topic.csdn.net/u/20120405/10/815acda1-0e12-4b7d-aa89-1d2f68a60704.html
由于较早前另一个雷同帖子:http://topic.csdn.net/u/20120102/01/fc8d7aa4-bffc-4d9a-a34a-5056c6d27b54.html 的作者hengyunabc对其原创性有异议(……
[/Quote]

LZ的汇编很强大,有没有 SSE 4.2 的


VS 2010 自带的情况, c++ = 3.879s, sse = 1.395s
intel 编译器,各种不同的优化组合选项:
1.851s/1.591s ,
1.843s/1.811s
1.914s/1.914s





## VS 2010

/Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D "_MBCS" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\ttt.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue


Sum of 0 to 9999 = 49995000 (sum1), 49995000 (sum2)

Time elapsed of sum1 (c++) is: 3.879s
Time elapsed of sum2 (asm ssse3) is: 1.395s



## intel parallel studio 2011 xe
# Quse-intel-optimized-headers 使用Intel优化的头文件
# QxSSE4.2 , 运行使用 sse 4
# Qparallel , 自动并行

/Zi /nologo /W3 /O3 /Oi /Ot /Qipo /GA /Qopt-matmul /Qparallel /Quse-intel-optimized-headers /D "_MBCS" /EHsc /GS /Gy /fp:precise /QxSSE4.2 /Zc:wchar_t /Zc:forScope /Fp"Release\ttt.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd

Sum of 0 to 9999 = 49995000 (sum1), 49995000 (sum2)

Time elapsed of sum1 (c++) is: 1.851s
Time elapsed of sum2 (asm ssse3) is: 1.591s


## intel parallel studio 2011 xe
# QxSSE4.2 , 运行使用 sse 4

/Zi /nologo /W3 /O3 /Oi /Ot /Qipo /GA /Qopt-matmul /D "_MBCS" /EHsc /GS /Gy /fp:precise /QxSSE4.2 /Zc:wchar_t /Zc:forScope /Fp"Release\ttt.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd
Sum of 0 to 9999 = 49995000 (sum1), 49995000 (sum2)

Time elapsed of sum1 (c++) is: 1.843s
Time elapsed of sum2 (asm ssse3) is: 1.811s
Sum of 0 to 9999 = 49995000 (sum1), 49995000 (sum2)


## intel parallel studio 2011 xe
# QxSSE4.2 , 运行使用 sse 4
# Qparallel , 自动并行

/Zi /nologo /W3 /O3 /Oi /Ot /Qipo /GA /Qopt-matmul /Qparallel /D "_MBCS" /EHsc /GS /Gy /fp:precise /QxSSE4.2 /Zc:wchar_t /Zc:forScope /Fp"Release\ttt.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd
Time elapsed of sum1 (c++) is: 1.914s
Time elapsed of sum2 (asm ssse3) is: 1.587s



hubo520891 2012-04-23
  • 打赏
  • 举报
回复
一目了然
用户 昵称 2012-04-22
  • 打赏
  • 举报
回复
哇,俺看到了zyl910,这么好的贴子干吗这么快就结了呢?
  • 打赏
  • 举报
回复
多谢。
zyl910 2012-04-21
  • 打赏
  • 举报
回复
测试了一下Intrinsics函数,还测试了64位版的性能。
详见——
http://topic.csdn.net/u/20120102/01/fc8d7aa4-bffc-4d9a-a34a-5056c6d27b54.html
用户 昵称 2012-04-16
  • 打赏
  • 举报
回复
好贴怎么没人顶了,赵老师那个汇编俺还能看懂,楼主的俺是不想懂了。
加载更多回复(26)

64,692

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧