除以N除以N ^ 2之前两次除以?

时间:2014-02-04 00:46:27

标签: c++ optimization division divide

任何人都可以回答为什么这句话:

unsigned int index; 
unsigned int i;  
unsigned int n;  
while (condition) {
    i = index / n / n;
}

快于:

unsigned int index; 
unsigned int i;  
unsigned int n;  
unsigned int n2 = n * n;  

while (condition) {
    i = index / n2;
}

很奇怪,这是我演示的视频:[删除]

该语句运行400,000次或最终减慢0.15秒。我正在清理我的.o文件,并在每次运行测试时使用-O3优化重新构建。在Red Hat 4.4.7-4上使用gcc(GCC)4.4.7 20120313

更新

根据建议我将其转换为装配以检查出来。我对装配的有限知识并没有揭示答案,事实上似乎更快的解决方案需要更长的时间,因为更多的操作

 128:utils.cpp     ****         i = index / farm_size / farm_size;
 1221                   .loc 8 129 0
 1222 046a 8B459C           movl    -100(%rbp), %eax
 1223 046d BA000000         movl    $0, %edx
 1223      00
 1224 0472 F7B57CFF         divl    -132(%rbp)
 1224      FFFF
GAS LISTING /tmp/cc4vphk8.s             page 44
 1225 0478 BA000000         movl    $0, %edx
 1225      00
 1226 047d F7B57CFF         divl    -132(%rbp)
 1226      FFFF
 1227 0483 8945B8           movl    %eax, -72(%rbp)
 129:utils.cpp     ****         j = (index / farm_size) % farm_size;

 128:utils.cpp     ****         i = index / farm_area;
 1221                   .loc 8 129 0
 1222 046a 8B459C           movl    -100(%rbp), %eax
 1223 046d BA000000         movl    $0, %edx
 1223      00
 1224 0472 F775D8           divl    -40(%rbp)
 1225 0475 8945B8           movl    %eax, -72(%rbp)
GAS LISTING /tmp/ccNU8jKx.s             page 44
 129:utils.cpp     ****         j = (index / farm_size) % farm_size;

这是一个并排的比较:

http://i.imgur.com/mB4OeFM.png

1 个答案:

答案 0 :(得分:3)

您的视频中有一些重要信息未放入代码中。

此处显示了在1.15秒内运行的双分码

enter image description here

此处显示了在1.34秒内运行的单分区代码: enter image description here

在发布的问题中不明显的一个重要区别是循环中的变量集。

在速度更快的代码中,您有ijkindexfarm_size

在较慢的代码中,您有ijkindexfarm_size {{ 1}}。

所以即使你做了一个较少的分工,你也会转移更多的变量,这就是花费额外时间的成本。