【发布时间】:2016-04-01 17:48:19
【问题描述】:
我有一个函数,出于性能原因,我在其中键入双关语。基本上,我有一个 32×32 位数组存储为 32 个 uint32s 的数组:
struct Tile {
uint32_t d[32];
};
然后我想计算 32×32 瓷砖的 28×28“内部”的人口(“1”的数量)。简单的方法需要 28 次调用机器的 popcnt 指令,每行一个。但是,由于 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")))
那么 g++ 会出于明显的原因不断抱怨我的类型双关语:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
const uint64_t v = *reinterpret_cast<const uint64_t*>(sqt->d + i);
另一方面,如果我包含该属性,某些版本的 g++ 会抱怨,而其他版本则不会。在我尝试过的机器中,我得到:
- g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 抱怨
- g++-4.6.real (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 不抱怨
- g++ (Debian 5.3.1-5) 5.3.1 20160101 不抱怨
g++ 4.8.4 的 Ubuntu 风格有什么问题?
【问题讨论】:
-
出于性能原因,我在打双关语——这里是个谬论。