Avatar ·

将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