如何生成一个sse4.2 popcnt机器指令

Ala*_*itz 14 optimization gcc bit-manipulation hammingweight

使用c程序:

int main(int argc , char** argv)
{

  return  __builtin_popcountll(0xf0f0f0f0f0f0f0f0);

}
Run Code Online (Sandbox Code Playgroud)

和编译器行(gcc 4.4 - Intel Xeon L3426):

gcc -msse4.2 poptest.c -o poptest
Run Code Online (Sandbox Code Playgroud)

我没有得到内置的popcnt insruction,而是编译器生成一个查找表并以这种方式计算popcount.生成的二进制文件超过8000个字节.(东旭!)

非常感谢您的帮助.

Tor*_*gen 26

您必须告诉GCC为支持popcnt指令的体系结构生成代码:

gcc -march=corei7 popcnt.c
Run Code Online (Sandbox Code Playgroud)

或者只是启用popcnt支持:

gcc -mpopcnt popcnt.c
Run Code Online (Sandbox Code Playgroud)

在您的示例程序中,参数to __builtin_popcountll是一个常量,因此编译器可能会在编译时进行计算,并且永远不会发出popcnt指令.即使没有要求优化程序,GCC也会这样做.

所以尝试传递它在编译时无法知道的东西:

int main (int argc, char** argv)
{
    return  __builtin_popcountll ((long long) argv);
}

$ gcc -march=corei7 -O popcnt.c && objdump -d a.out | grep '<main>' -A 2
0000000000400454 <main>:
  400454:       f3 48 0f b8 c6          popcnt %rsi,%rax
  400459:       c3                      retq
Run Code Online (Sandbox Code Playgroud)


Pau*_*l R 4

你需要这样做:

#include <stdio.h>
#include <smmintrin.h>

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

$ gcc -Wall -m64 -msse4.2 popcnt.c -o popcnt
$ ./popcnt 
pop = 32
$ 
Run Code Online (Sandbox Code Playgroud)

编辑

哎呀 - 我刚刚使用 gcc 4.2 和 ICC 11.1 检查了反汇编输出 - 而 ICC 11.1 正确生成了popcntlor popcntq,由于某种原因 gcc 没有 - 它调用___popcountdi2了。诡异的。当我有机会时,我会尝试更新版本的 gcc,看看它是否已修复。我想唯一的解决方法是使用 ICC 而不是 gcc。