无意中看到了pytorch中关于power(2, floor(log2(n))) 的操作方法, 其c++运行时间:
方法1: 使用math自带的log函数以及power进行计算:(我实现的,有点蠢,,,,)
static inline int GetLastPow2(int n) {
n = log2(n);
n = max(0, n);
return std::pow(2, n);
}
方法2: pytorch实现的,通过位移以及逻辑或的方式计算:(nice。。。)
static inline int last_pow2(int n) {
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return std::max(1, n - (n >> 1));
}
然后憨憨的我表示不服,于是测试了对应的运行时间:
同时计算比4099小的2的幂:
double start, end;
unsigned int m = 4099;
unsigned int t = 0;
int tp;
//获取pytorch实现对应的开始时间
start = cpuSecond() * 1000; // 将时间转化为ms
for(int i = 0; i < 1000; i++) {
tp = last_pow2(4099);
}
//获取pytorch实现对应的结束时间
end = cpuSecond() * 1000;
printf("--------> %f ms\n", end - start);
//获取憨憨实现对应的开始时间
start = cpuSecond() * 1000;
for(int i = 0; i < 1000; i++) {
t = GetLastPow2(4099);
}
//获取憨憨实现对应的开始时间
end = cpuSecond() * 1000;
printf("->>>>>>>> %f ms\n", end - start);
运行结果:
--------> 0.012207 ms // Pytorch
->>>>>>>> 0.145996 ms // 本憨憨
后来从网上又看到了第三种实现:参考链接:https://blog.csdn.net/qq_41709801/article/details/88371152
unsigned hight_bit(unsigned x){//0010 1100 0000 0000 0000 0000 0000 0000 0000 0001
x= x|(x>>1); //0011 1110 0000 0000 0000 0000 0000 0000 0000 0000
x= x|(x>>2); //0011 1111 1000 0000 0000 0000 0000 0000 0000 0000
x= x|(x>>4); //0011 1111 1111 1000 0000 0000 0000 0000 0000 0000
x= x|(x>>8); //0011 1111 1111 1111 1111 1000 0000 0000 0000 0000
x= x|(x>>16); //0011 1111 1111 1111 1111 1111 1111 1111 1111 1111
x= x|(x>>32);
// 如果数特别大, 这里感觉会溢出, 所以这里只使用于小于数据最大值1/2的数。
return (x+1) >> 1; //0100 0000 0000 0000 0000 0000 0000 0000 0000 0000
}
增加cpu运行时间对比:
--------> 0.011963 ms //pytorch
->>>>>>>> 0.145996 ms //本憨憨
-<<<<<<<< 0.007812 ms // 第三种实现: 真香
第三种真香!!!