私はパフォーマンス上の理由から型打ちを行う関数を持っています。基本的に、私は32 uint32sの配列として格納された32×32ビットの配列を持っている:-fno-strict-aliasingを関数属性として指定します。
struct Tile {
uint32_t d[32];
};
私はその後、内部28「・バイ・28の(1の人口の数) 『を計算したいです』 32×32タイルの素朴な方法では、マシンのpopcnt命令を各行に1つずつ、28回コールします。しかしPOPCNTは、64ビットの引数を取ることができるので、これは14回のPOPCNT呼び出しに減らすことができます:私は属性含まれていない場合は
int countPopulation(Tile* sqt) __attribute__((optimize("-fno-strict-aliasing"))) {
int pop = 0;
for (int i = 2; i < 30; i += 2) {
const uint64_t v = *reinterpret_cast<const uint64_t*>(sqt->d + i);
pop += __builtin_popcountll(v & 0x3ffffffc3ffffffcull);
}
return pop;
}
:その後、
__attribute__((optimize("-fno-strict-aliasing")))
グラムを++私は私をすれば、一方
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
const uint64_t v = *reinterpret_cast<const uint64_t*>(sqt->d + i);
:常に私のタイプ-punningについて、明白な理由のために、文句を言うでしょう特定のバージョンのg ++が不平を言っているのに対し、属性をncludeしています。私はこれを試したているマシンの中で、私が取得:
- グラム++(Ubuntuの〜14.04.1 4.8.4-2ubuntu1)4.8.4 がg ++
- を不平を言う - 4.6.real(Ubuntuの/リナロ4.6.3-1ubuntu5)4.6.3 は
- グラム++(Debianの5.3.1-5)5.3.1 20160101 をgのUbuntuの味と間違って何
を文句はありません文句はありません++ 4.8.4?
*私はパフォーマンス上の理由からタイプ・パンニングしています* - ここでは誤りがあります。 – SergeyA