摘要
文章调查了更换 32 位循环计数器时遇到的性能偏差使用 _mm_popcnt_u64 内在函数在性能关键循环中使用 64 位计数器。该问题导致 Intel CPU 的性能显着下降,从而导致执行速度不同。作者探讨了这种行为背后的原因并提供了潜在的解决方案。
详细信息
相关代码涉及一个迭代数据数组并执行 popcount 的循环使用 x86 内部指令进行操作。循环计数器变量最初是一个无符号整数,但将其替换为 64 位无符号整数(uint64_t)导致性能下降约 50%。
为了调查原因,作者编译了代码:各种优化标志并分析了生成的汇编代码。他们观察到32位和64位版本生成了不同的程序集,导致他们怀疑编译器存在错误。
但是,在使用不同的编译器测试代码后,作者得出的结论是问题不在于由编译器错误引起,而不是由硬件中的错误数据依赖性引起。 _mm_popcnt_u64 指令在 Intel Sandy/Ivy Bridge 和 Haswell 处理器上使用时,会表现出对目标寄存器的错误依赖性,其中指令会等到目标准备好后再执行。这种错误的依赖关系可能会跨循环迭代,从而阻止处理器并行化不同的迭代并导致性能损失。
作者提出了内联汇编测试,通过隔离 popcount 操作并打破错误依赖关系来演示性能差异链。这些测试表明,错误的依赖关系对性能有显着影响,导致速度从 18.6195 GB/s 降低至 8.49272 GB/s。
文章还强调该问题影响 Intel CPU,而 AMD 处理器似乎没有这个假
解决方案
为了缓解此性能问题,作者建议了几种解决方案:
以上是为什么在 Intel CPU 上用 64 位替换 32 位循环计数器会导致'_mm_popcnt_u64”性能下降?的详细内容。更多信息请关注PHP中文网其他相关文章!