14

この固定の最小限の実装を検討してください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のライブ サンプル

Godbolt のスクリーンショット - ベクトル化されていない


次の変更のいずれかを行うと...

  • values[size()]->values[_size]

  • __attribute__((always_inline))に追加size()

...その後、コンパイラはベクトル化されたアセンブリを生成します: Godbolt.org のライブ サンプル

Godbolt のスクリーンショット - ベクター化


これはgccのバグですか?または、明示的に追加されsize()ない限り、単純なアクセサーが自動ベクトル化を妨げる理由はありますか?always_inline

4

2 に答える 2