c – 英特尔编译器生成的代码比MSVC慢68%(提供完整示例)

前端之家收集整理的这篇文章主要介绍了c – 英特尔编译器生成的代码比MSVC慢68%(提供完整示例)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有C代码处理来自一个1800元素阵列的三个连续值.由ICC 14.0编译的代码比MSVC生成代码慢约68%(1600对2700 cpu周期).我不明白为什么.有人可以帮忙吗?即使我设置英特尔编译器-O3开关,它也不会改变时序. cpu是Ivy Bridge.
  1. #include <iostream>
  2.  
  3. int main(){
  4. int data[1200];
  5.  
  6. //Dummy-populate data
  7. for(int y=0; y<1200; y++){
  8. data[y] = y/2 + 7;
  9. }
  10.  
  11. int counter = 0;
  12.  
  13. //Just to repeat the test
  14. while(counter < 10000){
  15.  
  16. int Accum = 0;
  17. long long start = 0;
  18. long long end = 0;
  19. int p = 0;
  20.  
  21. start = __rdtsc();
  22.  
  23. while(p < 1200){
  24. unsigned int level1 = data[p];
  25. unsigned int factor = data[p + 1];
  26. Accum += (level1 * factor);
  27. p = p + 2;
  28. }
  29.  
  30. end = __rdtsc();
  31. std::cout << (end - start) << " " << Accum << std::endl;
  32. counter++;
  33. }
  34. }

解决方法

ICC在这里很糟糕,因为它正在计算每个数据的地址[n]访问ala mov edi,dword ptr [rsp rax * 4 44h] …所有运行时乘法都很昂贵.您应该能够通过重新编码来避免它,因此索引是常量(也可以使用* p_data三次,但这会引入可能对性能产生负面影响的排序问题).
  1. for (unsigned* p_data = &data[0],*p_end = data + 1800; p_data < p_end; p_data += 3)
  2. {
  3. unsigned level1 = p_data[0];
  4. unsigned level2 = p_data[1];
  5. unsigned factor = p_data[2];
  6.  
  7. Accum1 += level1 * factor;
  8. Accum2 += level2 * factor;
  9. }

猜你在找的C&C++相关文章