考虑以下valarray
类:
#include <stdlib.h>
struct va
{
void add1(const va& other);
void add2(const va& other);
size_t* data;
size_t size;
};
void va::add1(const va& other) {
for (size_t i = 0; i < size; ++i) {
data[i] += other.data[i];
}
}
void va::add2(const va& other){
for (size_t i = 0, s = size; i < s; ++i) {
data[i] += other.data[i];
}
}
该add2
函数针对不同的编译器(MSVC、Clang、GCC、ICC)进行了向量化,而add1
并非如此。参见https://godbolt.org/z/c61qvrrbv
这是通过潜在的别名来解释的:编译器无法证明所指向的元素之一data
不是其size
本身。
data
然而,和指向的元素也可能存在重叠other.data
。对于 MSVC,这些元素和指针本身可能存在别名,因为它没有利用严格别名规则。这适用于add1
和add2
。
编译器正在检查他们怀疑的所有可能的别名,并执行向量化操作add2
。
他们为什么不添加更多检查并进行优化add1
?