将32位循环计数器替换为64位导致Intel CPU上_mm_popcnt_u64出现奇怪的性能波动
大家好!我正在编写一个高性能函数,用于计算大数组中64位整数的置位位数(popcount)。我使用了SSE4.2中的内联函数`_mm_popcnt_u64`。代码很简单——一个循环,对每个元素累加popcount。
我发现了一个奇怪的行为:如果将循环变量声明为`uint32_t`,函数运行得非常快。但一旦将其替换为`uint64_t`(只需更改`i`的类型),性能几乎下降了一半!我在多个Intel Core i7(Sandy Bridge、Haswell、Skylake)上测试过——效果一致。编译器是MSVC 2010,不过在GCC 4.6.3上也有类似情况。优化选项已启用(/O2或-O2)。
以下是最小示例代码:
```cpp
#include
#include
#include
#include
// 使用32位计数器的快速版本
uint64_t popcnt32(const uint64_t* data, size_t size) {
uint64_t result = 0;
for (uint32_t i = 0; i < size; ++i) { // <-- 32位
result += _mm_popcnt_u64(data[i]);
}
re