深入探讨用位掩码代替分支(9):测试成绩总结

一、测试结果汇总

  将前面的测试结果进行汇总,按照三点取中方式筛选结果,整理为表格(单位是毫秒,数值越小越好)——

测试f0_iff1_minf2_negf3_sarf4_mmxf5_sse
VC6 on 32bit2016206371967237.525.7
VC6 on 64bit2028207571868737.125.3
VC2010(32) on 32bit17932112512437
VC2010(32) on 64bit17162106514437
VC2010(64) on 64bit16231997421328
C#2010(any) on 32bit192221472471559
C#2010(any) on 64bit187119182406651
C#2010(x86) on 32bit193021422462545
C#2010(x86) on 64bit182920732340516
C#2010(x64) on 64bit186519112399651
VB6 on 32bit2844 1078
VB6 on 64bit2839 1061

注:CPU:Intel Core i3-2310M, 2100 MHz。

  对应图表——

  上图是以毫秒为单位,因数据量很多,看起来有点吃力。于是又做了一个表格,将各列的数据除以“f0_if”列,即以倍数为单位,数值越大越好——

测试f0_iff1_minf2_negf3_sarf4_mmxf5_sse
VC6 on 32bit1.00 0.98 2.80 3.00 53.76 78.44
VC6 on 64bit1.00 0.98 2.82 2.95 54.66 80.16
VC2010(32) on 32bit1.00 0.85 3.50 4.10
VC2010(32) on 64bit1.00 0.81 3.34 3.93
VC2010(64) on 64bit1.00 0.81 3.86 4.95
C#2010(any) on 32bit1.00 0.90 0.78 3.44
C#2010(any) on 64bit1.00 0.98 0.78 2.87
C#2010(x86) on 32bit1.00 0.90 0.78 3.54
C#2010(x86) on 64bit1.00 0.88 0.78 3.54
C#2010(x64) on 64bit1.00 0.98 0.78 2.86
VB6 on 32bit1.00  2.64
VB6 on 64bit1.00  2.68

  对应图表(因MMX/SSE的性能太鹤立鸡群,影响图表阅读,故省略)——


二、各算法的性能分析

  现在我们按照列顺序(即各个算法的顺序)来进行分析——
1.首先,f0_if是采用if语句的基础算法,当作标杆用来评比其他算法。
2.f1_min采用了系统函数min、max。因现代编译器会对min、max做内联优化的,理论上应该与f0_if差不多。但实际测试后发现,f1_min比f0_if慢了一些。原因可能是因为min/max的语义与if不同,编译优化的深度不及if语句。
3.f2_neg算法采用了位运算来避免分支跳转,处理速度有了较大提高,平均性能大约是f0_if的3倍。可惜C#不支持将bool型强制转换为整型,而调用Convert.ToInt16带来了性能开销,使其比f0_if还慢。
4.f3_sar算法利用带符号移位避免了状态寄存器的访问,处理速度又有了一定的提升,平均性能大约是f0_if的3.5倍。
5.f4_mmx、f5_sse算法因为用到MMX、SSE这些SIMD指令集,所以处理速度比前面那些高级语言算法高了一个级别。

算法最小倍数最大倍数平均倍数备注
f1_min0.810.980.91无VB6
f2_neg2.643.863.09无C#
f3_sar2.864.953.52无VB6
f4_mmx53.7654.6654.21仅VC6
f5_sse78.4480.1679.3仅VC6


三、其他发现

  分析测试结果,还发现——
1.VC2010的的编译优化能力比VC6要强,同样程序的运行速度要快很多。这可能是因为VC2010的编译优化更能适应最新处理器的指令级并行性。
2.在64位系统中能运行32位程序,除了C#以外,其运行速度与在32位系统中的差不多。
3.C#2010的程序,有时在64位系统上的运行速度比32位系统还慢,甚至包括了“x64”平台方式编译的程序。似乎“x86”平台方式编译的程序的平均性能最好。可能是因为64位JIT(即时编译器)不如32位的成熟。
4.对于VC2010编译器来说,编译的64位程序比32位程序的运行速度有比较明显的提升。看来编写64位程序的最好还是用VC等C/C++编译器。
5.在传统印象中,VB、C#的运行速度比C语言慢很多。但通过这次测试发现,虽然它们的性能是有一定差距,但是是处于同一级别的,甚至C#与VC6打平还略占优势。影响程序运算速度的最关键因素是算法,用编译能力最差的VB6实现的f2_neg,比编译能力最好的VC2010实现的f0_if要快得多。


四、总结

  使用位掩码代替分支能带来较大的性能提升,而且该方案能推广到任何高级语言,能充分利用高级语言的可移植性,能满足大多数的性能优化需求。
  但当对性能要求极高、且不要求可移植性时,强烈推荐MMX、SSE等SIMD指令集,能使处理速度提高一个级别。

 

附:测试程序打包下载——
http://files.cnblogs.com/zyl910/noif_Test.rar
http://dl.dbank.com/c069c6thd7

(完)


《深入探讨用位掩码代替分支》系列文章——
1、利用带符号移位生成掩码:http://blog.csdn.net/zyl910/article/details/7345655
2、汇编代码分析:http://blog.csdn.net/zyl910/article/details/7378171
3、VC6速度测试:http://blog.csdn.net/zyl910/article/details/7399236
4、VC2010速度测试:http://blog.csdn.net/zyl910/article/details/7403497
5、C#2010速度测试:http://blog.csdn.net/zyl910/article/details/7408013
6、VB6速度测试:http://blog.csdn.net/zyl910/article/details/7412216
7、MMX指令集速度测试:http://blog.csdn.net/zyl910/article/details/7443141
8、SSE指令集速度测试:http://blog.csdn.net/zyl910/article/details/7455830
9、测试成绩总结:http://blog.csdn.net/zyl910/article/details/7458757

 

 

 

 

网友的测试成绩
~~~~~~~~~~~~~~

参与帖子——
http://topic.csdn.net/u/20120413/17/11aaf5cb-6ca1-4477-9271-2f071435e9f8.html
http://topic.csdn.net/u/20120413/17/d0f0dd3f-ca55-41f6-9fa0-321a85be5668.html

 

成绩汇总——

测试CPUGHzf0_iff1_minf2_negf3_sarf4_mmxf5_sse倍f1倍f2倍f3倍f4倍f5idtime
1VC2010(32) on 32bitIntel G5302.8015061854447382  0.813.373.94  dianyancao2012-4-13 18:10
2VC6 on 32bitIntel Celeron2.4028443422192117961191.41303.80.831.481.582.392.18laviewpbt2012-4-14 9:35
3VC2010(32) on 32bitIntel Celeron2.405984773526092547  0.772.292.35  laviewpbt2012-4-14 9:35
4VB6 on 32bitIntel Celeron2.407609 3329    2.29   laviewpbt2012-4-14 9:35
5VC6 on 32bitIntel i3 380M2.53360229371563153075.041.61.232.302.3548.0386.59laviewpbt2012-4-14 13:40
6VC2010(32) on 32bitIntel i3 380M2.5324152929497388  0.824.866.22  laviewpbt2012-4-14 13:40
7C#2010(any) on 32bitIntel i3 380M2.53296718462372476  1.611.256.23  laviewpbt2012-4-14 13:40
8C#2010(x86) on 32bitIntel i3 380M2.53239118342371472  1.301.015.07  laviewpbt2012-4-14 13:40
9VB6 on 32bitIntel i3 380M2.538115 2240    3.62   laviewpbt2012-4-14 13:40
10VB6 on 32bitAMD 四核2.002108 1260    1.67   Veron_042012-4-14 14:56
11VC6 on 32bitIntel i7 2620M2.7014521529498495  0.952.922.93  unicodestring2012-4-16 21:52
12VC6 on 32bit18131981780751105.3108.50.922.322.4117.2216.71likid14122012-4-16 21:52
13VC6 on 64bitIntel i7 9202.602048157296481638.825.71.302.122.5152.7879.69CandPointer2012-4-17 4:24
14VC2010(32) on 64bitIntel i7 9202.6015112181420322  0.693.604.69  CandPointer2012-4-17 4:24
15VC2010(64) on 64bitIntel i7 9202.6014511557383248  0.933.795.85  CandPointer2012-4-17 4:24
16C#2010(any) on 64bitIntel i7 9202.60154015472064403  1.000.753.82  CandPointer2012-4-17 4:24
17C#2010(x86) on 64bitIntel i7 9202.60206115902052411  1.301.005.01  CandPointer2012-4-17 4:24
18C#2010(x64) on 64bitIntel i7 9202.60153915542069404  0.990.743.81  CandPointer2012-4-17 4:24
19VC6 on 32bitIntel i5 520M2.40225818481070101352.731.81.222.112.2342.8571.01VBAdvisor2012-4-17 7:58
20VC2010(32) on 32bitIntel i5 520M2.4017822512583432  0.713.064.13  VBAdvisor2012-4-17 7:58
21C#2010 on 32bitIntel i5 520M2.40248817622326494  1.411.075.04  VBAdvisor2012-4-17 7:58
22C#2010(any) on 32bitIntel i5 520M2.40226217852352469  1.270.964.82  VBAdvisor2012-4-17 7:58
23VB6 on 32bitIntel i5 520M2.402874 1386    2.07   VBAdvisor2012-4-17 7:58
24VC6 on 32bitInter Core2 E65502.3324861840102099458.941.31.352.442.5042.2160.19Tiger_Zhao2012-4-17 10:40
25VB6 on 32bitInter Core2 E65502.332791 1252    2.23   Tiger_Zhao2012-4-17 10:40
26VC6 on 64bitIntel i5 560M2.402117171591292642.828.41.232.322.2949.4674.54ggt871252012-4-17 10:43
27VC2010(32) on 64bitIntel i5 560M2.4016172345463353  0.693.494.58  ggt871252012-4-17 10:43
28VC2010(64) on 64bitIntel i5 560M2.4015581687433301  0.923.605.18  ggt871252012-4-17 10:43
29C#2010(any) on 64bitIntel i5 560M2.40165816842229453  0.980.743.66  ggt871252012-4-17 10:43
30C#2010(x86) on 64bitIntel i5 560M2.40222017092222450  1.301.004.93  ggt871252012-4-17 10:43
31C#2010(x64) on 64bitIntel i5 560M2.40164316742240447  0.980.733.68  ggt871252012-4-17 10:43
32VC6 on 32bitIntel i3 21203.301296131345343823.416.60.992.862.9655.3878.07chenjl10312012-4-17 11:40
33VC2010(32) on 32bitIntel i3 21203.3010781328328281  0.813.293.84  chenjl10312012-4-17 11:40
34VB6 on 32bitIntel i3 21203.301813 687    2.64   chenjl10312012-4-17 11:40
35VC6 on 32bitIntel Pentium E55002.802139158385882750.334.41.352.492.5942.5262.18bigbaldy2012-4-17 13:01
36VC2010(32) on 32bitIntel Pentium E55002.8014672177389342  0.673.774.29  bigbaldy2012-4-17 13:01
37C#2010(any) on 32bitIntel Pentium E55002.80199116172082442  1.230.964.50  bigbaldy2012-4-17 13:01
38C#2010(x86) on 32bitIntel Pentium E55002.80201315882013450  1.271.004.47  bigbaldy2012-4-17 13:01
39VB6 on 32bitIntel Pentium E55002.802363 1050    2.25   bigbaldy2012-4-17 13:01
40VC6 on 32bitIntel Pentium E53002.602250167290689152.837.11.352.482.5342.6160.65CandPointer2012-4-17 14:22
41C#2010(any) on 32bitIntel Pentium E53002.60210516752149468  1.260.984.50  CandPointer2012-4-17 14:22
42C#2010(x86) on 32bitIntel Pentium E53002.60210816782151468  1.260.984.50  CandPointer2012-4-17 14:22
43C#2010(any) on 32bitIntel Pentium E53002.60215817072192482  1.260.984.48  xinzhongyoucheng2012-4-18 8:55
44C#2010(x86) on 32bitIntel Pentium E53002.60215917102196475  1.260.984.55  xinzhongyoucheng2012-4-18 8:55
45VB6 on 32bitIntel Pentium E53002.602574 1132    2.27   xinzhongyoucheng2012-4-18 8:55

目前发现——
1.f1_min(使用min、max函数做饱和处理)有时是比f0_if(使用if分支做饱和处理)要快的。但差距不大。
2.对于较老的CPU,VC6编译的程序比VC2010编译的程序要快。可能是因为VC2010是为最新的CPU优化的。
3.Celeron处理上的MMX、SSE指令集的运行速度较慢,没能与高级语言算法拉开差距。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值