如何在我的计算机上启用POPCNT指令/内置支持?

9

我尝试在我的电脑(Fedora 17 32位)上运行以下程序。如何使我的系统支持popcnt指令以实现快速人口统计?

#include <stdio.h>
#include <nmmintrin.h>

int main(void)
{
    int pop = _mm_popcnt_u32(0xf0f0f0f0ULL);
    printf("pop = %d\n", pop);
    return 0;
}

我编译了程序并运行,但出现了以下异常:
[xiliu@xiliu tmp]$ gcc -Wall -march=corei7 -m32 -msse4.2 popcnt.c -o popcnt
[xiliu@xiliu tmp]$ ./popcnt 
Illegal instruction (core dumped)

以下是我的处理器信息:
[xiliu@xiliu tmp]$ cat /proc/cpuinfo 
processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 15
model name  : Intel(R) Pentium(R) Dual  CPU  T2370  @ 1.73GHz
stepping    : 13
microcode   : 0xa4
cpu MHz     : 800.000
cache size  : 1024 KB
physical id : 0
siblings    : 2
core id     : 0
cpu cores   : 2
apicid      : 0
initial apicid  : 0
fdiv_bug    : no
hlt_bug     : no
f00f_bug    : no
coma_bug    : no
fpu     : yes
fpu_exception   : yes
cpuid level : 10
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm dtherm
bogomips    : 3458.20
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

[... repeated for 2nd core ...]

这是一个相当糟糕的例子;如果你使用启用了优化的gcc编译,二进制文件中将不会有popcnt指令,因为常量传播将把它转换为mov esi, 16(https://godbolt.org/z/h5ObTj)。然而,MSVC失败了,并仍然发出一个popcnt指令。 - Peter Cordes
3个回答

15

12
第一个支持 POPCNT 指令的 CPU 是英特尔的 Nehalem。看起来你的是旧的 Core 系列。Hasturkun 的建议可以在你的系统上运行,但会使用多个指令而非单个指令。
如果你想要一种可移植的解决方案而非针对 GCC 的解决方案,请查看 Sean Eron Anderson 的优秀的 位操作技巧 Bit Twiddling Hacks 页面,其中有高度优化的代码实现。

3
确实。换句话说,“popcnt”是作为SSE4的一部分添加的(而OP的T2370仅支持补充的SSE3)。 - Pascal Cuoq
3
POPCNT是在SSE4.2推出的同时引入的,但它并非SSE4.2的一部分。它有自己的CPUID位。 - Cory Nelson
3
尽管有可能显得过时,IBM的POWER5已经具备了POPCNT功能。http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.alangref/idalangref_popcntbd.htm?lang=it - jupp0r
2
@jupp0r:尽管有显得古老的危险,但我在20世纪70年代编程时使用的Control Data主机(如CDC 7300)具有popcount指令。它适用于60位字,并且需要比ADD等简单指令长得多的时间。 - Brendan McKay
2
@BrendanMcKay 你抓住我了 :) Cray-1也可以进行popcnt操作 (1975)。 - jupp0r

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接