10

我试图在 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()在地球上是如何运作的

4

2 回答 2

15

_mm_popcnt_u64<nmmintrin.h>是英特尔设计的用于访问 SSE 4.2 指令的实用程序功能的标头的一部分。

__builtin_popcountll是 GCC 扩展。

_mm_popcnt_u64可移植到非 GNU 编译器,并且__builtin_popcountll可移植到非 SSE-4.2 CPU。但是在两者都可用的系统上,两者都应该编译成完全相同的代码。

于 2017-06-13T16:19:11.197 回答
1

如果你编译时没有使用 March 标志,那么默认使用 x86_64,内置应该会更慢,因为它需要在不同架构之间调度函数选择。这将导致没有内联和附加条件。

于 2019-11-18T20:22:23.570 回答