【发布时间】:2018-07-23 21:04:57
【问题描述】:
考虑这个固定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");
编译器生成非向量化程序集:live example on godbolt.org
如果我做出任何以下更改...
values[size()]->values[_size]将
__attribute__((always_inline))添加到size()
...然后编译器生成向量化程序集:live example on godbolt.org
这是一个 gcc 错误吗? 或者,除非明确添加 always_inline,否则像 size() 这样的简单访问器会阻止自动矢量化吗?
【问题讨论】:
-
编译器可以隐含地告诉我返回的值将会改变是我的猜测。现代编译器非常擅长找出将要发生的变化,在这种情况下,
size的返回值保证在所有情况下都会发生变化。 -
另外将
__attribute__((const))添加到size()会导致应用自动矢量化(__attribute__((pure))不会)。 -
将
++_size放在类成员中会导致矢量化:godbolt.org/g/toBQc7 gcc 版本 5.x 和 6.x 也会生成矢量化代码:godbolt.org/g/wU6n8F -
这是一个错过的优化,与早期版本的编译器相比,gcc-7 中的回归 --> 请将其报告给 gcc 的 bugzilla。
-
@MarcGlisse:报告为gcc.gnu.org/bugzilla/show_bug.cgi?id=84362
标签: c++ performance gcc optimization auto-vectorization