14

cプログラムの使用:

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

  return  __builtin_popcountll(0xf0f0f0f0f0f0f0f0);

}

およびコンパイラライン(gcc 4.4-Intel Xeon L3426):

gcc -msse4.2 poptest.c -o poptest

組み込みのpopcnt命令を取得せず、コンパイラがルックアップテーブルを生成し、その方法でポップカウントを計算します。結果のバイナリは8000バイトを超えます。(ユク!)

助けてくれてありがとう。

4

3 に答える 3

26

popcnt 命令をサポートするアーキテクチャ用のコードを生成するように GCC に指示する必要があります。

gcc -march=corei7 popcnt.c

または popcnt のサポートを有効にします:

gcc -mpopcnt popcnt.c

サンプル プログラムでは、パラメータ 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
于 2012-11-03T18:10:23.270 に答える
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
$ 

編集

おっと-gcc 4.2とICC 11.1で逆アセンブリ出力を確認しました-ICC 11.1はpopcntlorを正しく生成しますpopcntqが、何らかの理由でgccは生成しません-___popcountdi2代わりに呼び出します。変。機会があれば、新しいバージョンの gcc を試して、修正されるかどうかを確認します。それ以外の唯一の回避策は、gcc の代わりに ICC を使用することだと思います。

于 2011-06-21T15:27:37.490 に答える