Considere a seguinte valarray
classe -like:
#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];
}
}
A add2
função é vetorizada para diferentes compiladores (MSVC, Clang, GCC, ICC), enquanto add1
não é. Veja https://godbolt.org/z/c61qvrrbv
Isso é explicado pelo possível aliasing: os compiladores não podem provar que um dos elementos apontados por data
não é o size
próprio.
No entanto, também há sobreposição potencial de elementos apontados por data
e other.data
. Para o MSVC, existe o potencial de aliasing desses elementos e ponteiros, pois não tira proveito da Strict Aliasing Rule. Isso se aplica a ambos add1
e add2
.
Os compiladores estão realizando verificações para todos os possíveis aliasing que suspeitam e executam operações vetorizadas para arquivos add2
.
Por que eles não estão adicionando mais verificações e tendo essa otimização para add1
?