使用`%`vs`&`时的时间差异/增加不同

时间:2012-10-05 03:18:51

标签: c++ performance

在尝试确定给定CPU的高速缓存大小时,我尝试将内存访问时间设置为内存/缓存,如:

lengthMod = sizes[i]/sizeof(int)  - 1; // where sizes[i] is something like 1024, 2048 ... 
for (unsigned int k = 0; k < REPS; k++) {
    data[(k * 16) & lengthMod]++;
}

1, 0.52 
4, 0.52 
8, 0.52 
16, 0.52 
32, 0.52 
64, 1.11 // << note the jump in timing. L1 cache size is 32K
128, 1.12 
256, 1.19 

所以我认为如果lengthMod不是2的幂,我就不能这样做。所以我试着做了

lengthMod = sizes[i]/sizeof(int);
for (unsigned int k = 0; k < REPS; k++) {
    data[(k * 16) % lengthMod]++;
}

1, 2.67 
4, 2.57 
8, 2.55 
16, 2.51 
32, 2.42 
64, 2.42 // << no jump anymore ...
128, 2.42 
256, 2.42

然后我发现我预期的时间增长不再存在......我预计时间会增加但它应该适用于所有值?因此,如果使用x&秒,我会期望~x+c秒(其中c近似不变),但事实并非如此,事实上,它减少了与不存在的时间差异为什么呢?

2 个答案:

答案 0 :(得分:3)

你所看到的是瓶颈的权衡。

  • 在第一个示例中,您的缓存带宽会受到瓶颈。
  • 在第二个示例中,您将受到整数除法的瓶颈。

在继续之前,让我们看看两个例子之间的区别:

  • 在第一种情况下,使用&这是一种快速按位操作。
  • 在第二种情况下,使用%这是非常慢的划分。

分部非常慢。当除数/模数是编译时常数时,现代编译器将尝试优化它们。

但事实并非如此。 因此,您需要支付硬件部门的全部费用。 这就是为什么第二个示例中的时间比第一个示例慢得多。


使用&,代码足够快以最大化缓存带宽。但是,对于%,代码要慢得多 - 不够快,无法跟上缓存。所以你一直看到同样的时间。

答案 1 :(得分:0)

在第二种情况下,编译器生成的优化代码较少(因为“与余数分开”)。