我在列表中存储了可变数量的位。我需要查找[i,j]范围内的位。目前,我将这些位存储在无符号32位整数的向量中。
这就是我查找的方式:
std::uint32_t
Data::findInt3(const std::vector<std::uint32_t>& input, int size, int pos) {
pos = pos*size;
int firstc = pos >> 5;
int ipos = pos & 31;
int end = ipos+size;
std::uint64_t t = input[firstc];
std::uint64_t num = (t << 32) | input[firstc+1];
std::uint64_t number = num >> (64-end);
number = number & ((1 << size)-1);
return number;
}
这段代码被称为很多次。我想只是小加速会非常有益。谁能看到任何可以做得更好的东西?喜欢换东西而不是换东西。或哪个更快?
由于
答案 0 :(得分:3)
这段代码执行了几件事:
因此,通过观察它,如果不显示它的使用方式,并且不了解整个算法,它看起来就不会被优化。这些操作已经看起来最佳。
如果它真的是在一个大循环中执行,那么我会这样做:
答案 1 :(得分:1)
首先是常见的事情:
size
,pos
和内部变量。你肯定这些需要签名整数吗?我实际上看到了一些你可以尝试的事情:
pos
参数拆分为其他值firstc
,ipos
和end
。我假设您的代码中的这些值以前也作为分隔值存在。将它们作为单独的参数直接传递可能会更好。如果不以此函数的更多参数为代价来获得此计算事件,则可以获得回报。你std::vector<std::uint64_t>
中,这样就可以节省一个&#34;查找&#34;,&#34;或&#34;和#34;位移&#34;。你能改变矢量类型吗?std::uint64_t number = num >> (64-end);
的计算看起来很可疑。是否无法以任何方式预先计算此值?number = number & ((1 << size)-1);
上的屏蔽操作。您需要支持多少种不同的尺寸?我想只有64个。你可以将所有可能的掩码放入(预先计算)std::vector<uint64_t> masks;
。通过这种方式,您可以将此行转换为:number &= masks[size];
向量查找几乎总是比移位操作更快。std::uint64_t number = num >> shiftvalue[end];
这将节省一次减法。答案 2 :(得分:1)
我尝试过一点优化你的代码,如果不需要,不要获取第二个数组元素。也许,这对小尺寸有帮助:
std::uint32_t
Data::findInt3(const std::vector<std::uint32_t>& input, int size, int pos) {
pos = pos*size;
int firstc = pos >> 5;
int ipos = pos & 31;
int end = ipos+size;
if(end > 32) {
std::uint64_t t = input[firstc];
std::uint64_t num = (t << 32) | input[firstc+1];
return (num >> (64-end)) & ((1L << size)-1);
} else {
return (input[firstc] >> (32-end)) & ((1 << size)-1);
}
}