[有奖问答]将整数乘以2的幂转化为移位操作速度反而慢了

不论是CPU还是GPU,一般来说总是将整数乘以2的幂转化为移位操作。
如下version 1和2 所示将tid*4转化为tid<<2,理论上应该加速的,但实际结果是ver 1比ver2快。
两个版本测了很多次,并且其太东西不变。

求合理可能的解释:

uint tid

version 1
des[tid * 4 + 0] = …;
des[tid * 4 + 1] = …;
des[tid * 4 + 2] = …;
des[tid * 4 + 3] = …;
__syncthreads();

__syncthreads();
float4 d;
d.x = __fdividef(des[tid * 4 + 0], len[0]);
d.y = __fdividef(des[tid * 4 + 1], len[0]);
d.z = __fdividef(des[tid * 4 + 2], len[0]);
d.w = __fdividef(des[tid * 4 + 3], len[0]);
d_des[idx * 16 + tid] = d;

version 2
des[(tid<<2)] = …;
des[(tid<<2) + 1] = …;
des[(tid<<2) + 2] = …;
des[(tid<<2) + 3] = …;
__syncthreads();

__syncthreads();
float4 d;
d.x = __fdividef(des[(tid<<2)], len[0]);
d.y = __fdividef(des[(tid<<2) + 1], len[0]);
d.z = __fdividef(des[(tid<<2) + 2], len[0]);
d.w = __fdividef(des[(tid<<2) + 3], len[0]);
d_des[(idx<<4) + tid] = d;

理论上速度一样,能否提供所有代码?

为什么理论上速度一样?位移操作应该比整数乘法速度快吧

sorry,是图像检索算法(surf),代码加测试集比较大,发不上来

因为乘的是常数,编译器会自动转化为移位,C编译器早就这么做了

可能的原因是编译器的优化造成的
地址访问A[ab+c]可能转化为
(a
b+c)d的形式。然后编译器会展开优化。abd+cd,其中b,d都是2的幂
但是如果我自己写成了(a<<e+c)*d,编译器可能就认不出来了。
估计是这个原因

我估计不是。移位再相加反而会更慢。根据手册,在2.0上,你的tid*4+offset需要一条指令(multiply-add), 2 clocks/cuda core. 而你的tid<<2 + offset,需要二条指令,分别是移位(2 clocks)和加法(1 clocks), 共3 clocks, 所以变慢了是正常的。