この固定の最小限の実装を検討してくださいvector<int>
。
constexpr std::size_t capacity = 1000;
struct vec
{
int values[capacity];
std::size_t _size = 0;
std::size_t size() const noexcept
{
return _size;
}
void push(int x)
{
values[size()] = x;
++_size;
}
};
次のテスト ケースがあるとします。
vec v;
for(std::size_t i{0}; i != capacity; ++i)
{
v.push(i);
}
asm volatile("" : : "g"(&v) : "memory");
コンパイラは、ベクトル化されていないアセンブリを生成します: Godbolt.orgのライブ サンプル
次の変更のいずれかを行うと...
values[size()]
->values[_size]
__attribute__((always_inline))
に追加size()
...その後、コンパイラはベクトル化されたアセンブリを生成します: Godbolt.org のライブ サンプル
これはgccのバグですか?または、明示的に追加されsize()
ない限り、単純なアクセサーが自動ベクトル化を妨げる理由はありますか?always_inline