Prima di sostituire un sacco del mio "vecchio" per i cicli con la gamma a base di cicli for, mi sono imbattuto qualche test con Visual Studio 2013:VC++ non è più vectorize semplice per i cicli con la sintassi gamma basata
std::vector<int> numbers;
for (int i = 0; i < 50; ++i) numbers.push_back(i);
int sum = 0;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) sum += *number;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//vectorization
for (auto __begin = numbers.begin(),
__end = numbers.end();
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//no vectorization :(
for (auto number : numbers) sum += number;
//no vectorization :(
for (auto& number : numbers) sum += number;
//no vectorization :(
for (const auto& number : numbers) sum += number;
//no vectorization :(
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
guardando lo smontaggio, standard per i cicli erano tutti vettorizzati:
00BFE9B0 vpaddd xmm1,xmm1,xmmword ptr [eax]
00BFE9B4 add ecx,4
00BFE9B7 add eax,10h
00BFE9BA cmp ecx,edx
00BFE9BC jne main+140h (0BFE9B0h)
ma gamma base per i cicli non erano:
00BFEAC6 add esi,dword ptr [eax]
00BFEAC8 lea eax,[eax+4]
00BFEACB inc ecx
00BFEACC cmp ecx,edi
00BFEACE jne main+256h (0BFEAC6h)
C'è qualche ragione per cui il compilatore non ha potuto vettorializzare questi loop?
Mi piacerebbe davvero usare la nuova sintassi, ma perdere la vettorizzazione è troppo brutto.
ho appena visto this question, così ho provato la bandiera /Qvec-report:2
, dando un altro motivo:
loop not vectorized due to reason '1200'
che è:
loop contiene dipendenze di dati di loop-effettuata che impediscono vettorializzazione. Diverse iterazioni di il loop interferiscono tra loro in modo tale che la vettorizzazione del loop produce risposte sbagliate, e l'auto-vettore non può dimostrare a se stesso che non ci sono tali dipendenze dei dati.
È lo stesso bug? (Ho anche provato con l'ultimo compilatore vC++ "Nov 2013 CTP")
Devo segnalarlo anche su MS connect?
modificare
Du ai commenti, ho fatto lo stesso test con un int serie cruda, invece di un vettore, in modo da nessuna classe iteratore è coinvolto, a soli puntatori prime.
Ora tutti i loop sono vettorizzati tranne i due cicli "simulati in base alla gamma".
compilatore dice che questo è dovuto al motivo '501':
variabile induzione non è locale; o il limite superiore non è invariante del ciclo.
Non capisco cosa sta succedendo ...
const size_t size = 50;
int numbers[size];
for (size_t i = 0; i < size; ++i) numbers[i] = i;
int sum = 0;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) sum += *number;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//vectorization ?!
for (auto number : numbers) sum += number;
//vectorization ?!
for (auto& number : numbers) sum += number;
//vectorization ?!
for (const auto& number : numbers) sum += number;
//vectorization ?!
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
Sembra che il compilatore non riesca a visualizzare il tipo di iteratore. Prova a usare l'emulazione 'for' basata su intervallo usando' & v [0] 'e' & v [0] + v.size() 'per confermare questo sospetto. –
@ DietmarKühl Se ho capito bene, ho provato: \t \t per (auto __begin = e numeri [0], \t \t __end = & numeri [0] + numbers.size(); \t \t __begin = __end; +! + __ inizio) { \t \t auto && ref = * __ inizio; \t \t somma + = rif; \t} Ma questo anche vettorializzare. – ThreeStarProgrammer57
Se la versione che utilizza i puntatori vettorializza il ciclo, chiaramente l'iteratore che avvolge il puntatore sconvolge il compilatore: il tipo restituito da 'std :: vector :: begin()' non deve essere 'T *' (o 'T const * '). Sembra che il compilatore non possa rilevare che questo iteratore non è altro che un involucro sottile sopra un puntatore. –