__builtin_popcountll和_mm_popcnt_u64有什么区别?

enxuqcxy  于 2023-10-16  发布在  其他
关注(0)|答案(3)|浏览(143)

我试图在512MB内存中找到多少个1,我发现了两个可能的方法,_mm_popcnt_u64()__builtin_popcountll()gcc内置。
_mm_popcnt_u64()据说使用CPU介绍SSE4.2,这似乎是最快的,__builtin_popcountll()预计使用表查找。
所以,我认为__builtin_popcountll()应该比_mm_popcnt_u64()慢一点。
然而,我得到了这样的结果:

两种方法所用的时间几乎相同。我很怀疑他们用同样的方式工作。
我也在popcntintrin.h中得到了这个

/* Calculate a number of bits set to 1. */
extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial___))
_mm_popcnt_u32 (unsigned int __X)
{
  return __builtin_popcount (__X);
}

#ifdef __x86_64__
extern __inline long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_popcnt_u64 (unsigned long long __X)
{
  return __builtin_popcountll (__X);
}
#endif

所以,我很困惑__builtin_popcountll()到底是如何工作的

e4eetjau

e4eetjau1#

_mm_popcnt_u64<nmmintrin.h>的一部分,<nmmintrin.h>是英特尔为访问SSE 4.2指令的实用程序功能设计的标头。
__builtin_popcountll是一个GCC扩展。
_mm_popcnt_u64可移植到非GNU编译器,__builtin_popcountll可移植到非SSE-4.2 CPU。但是在两者都可用的系统上,两者应该编译为完全相同的代码。

iecba09b

iecba09b2#

如果你编译时没有march标志,那么在x86_64默认情况下,内建应该会更慢,因为它需要在不同的架构之间分派函数选择。这将不会导致内联和附加条件。

vx6bjr1n

vx6bjr1n3#

除了任何其他考虑之外,你不能只对一个循环计时,然后将原始数字用于任何有意义的基准测试。
作为一个经验法则,如果它没有误差线(方差),它就不是一个适当的衡量标准。下一次尝试运行基准测试10次(或1000次),计算平均值和标准差,并确保其中一个结果比另一个结果更好/更差,具有较高的统计置信度,即。> 99.9%。
https://en.wikipedia.org/wiki/Standard_deviation#Estimation
顺便说一下,基准测试中0.1%的差异通常应该被认为是统计噪声,特别是如果你正在测量CPU性能或任何其他需要100个周期以下执行的函数。

相关问题