-fno-strict-aliasing as function attribute

时间:2016-04-01 17:48:20

标签: c++ ubuntu gcc g++

我有一个功能,其中出于性能原因我会打字。基本上,我有一个32×32位的数组存储为32 uint32s的数组:

struct Tile {

    uint32_t d[32];

};

然后,我想计算28乘28'内部'的数量(' 1' s)。 32乘32的瓷砖。天真的方法需要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风格有什么问题?

1 个答案:

答案 0 :(得分:0)

不要打字。没有理由这样做。而是正确使用config.i18n.load_path += Dir["#{Rails.root.to_s}/config/locales/**/*.yml"] config.i18n.load_path += Dir["#{Rails.root.to_s}/config/locales/**/*.{rb,yml}"] config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**' '*.{rb,yml}').to_s] 来复制memcpy()参数。优化器将完成其余的工作。