2015-05-08 15 views
13

Hier sind freie Funktionen, die das gleiche tun, aber im ersten Fall ist die Schleife nicht vektorisiert, aber in den anderen Fällen ist es. Warum das?Warum verhält sich die Vektorisierung bei fast demselben Code anders?

#include <vector> 

typedef std::vector<double> Vec; 

void update(Vec& a, const Vec& b, double gamma) { 
    const size_t K = a.size(); 
    for (size_t i = 0; i < K; ++i) { // not vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

void update2(Vec& a, const Vec& b, double gamma) { 
    for (size_t i = 0; i < a.size(); ++i) { // vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

void update3(Vec& a, size_t K, const Vec& b, double gamma) { 
    for (size_t i = 0; i < K; ++i) { // vectorized 
     a[i] = b[i] * gamma - a[i]; 
    } 
} 

int main(int argc, const char* argv[]) { 
    Vec a(argc), b; 
    update(a, b, 0.5); 
    update2(a, b, 0.5); 
    update3(a, a.size(), b, 0.5); 
    return 0; 
} 

Relevante Nachrichten vom Compiler (VS2013):

1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(7) : info C5002: loop not vectorized due to reason '1200' 
1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(13) : info C5001: loop vectorized 
1> c:\home\dima\trws\trw_s-v1.3\trws\test\vector.cpp(19) : info C5001: loop vectorized 

Von Kommentar von @tony

Reason 1200: „Loop enthält schleifengeführte Datenabhängigkeiten, die Vektorisierung verhindern. Verschiedene Wiederholungen der Schleife interferieren mit jedem anderen, so dass die Vektorisierung der Schleife falsche Antworten erzeugen würde, und der Auto-Vektorisierer c Annot beweisen, dass es solche Daten Abhängigkeiten nicht gibt. " source

+2

Versuchen Sie einen anderen Compiler? Andere (gcc und clang) vektorisieren alle 3 Funktionen. –

+1

Was ist "Grund 1200" dokumentiert? –

+1

Grund 1200: "Schleife enthält Schleifen-getragene Datenabhängigkeiten, die Vektorisierung verhindern. Verschiedene Iterationen der Schleife interferieren miteinander, so dass eine Vektorisierung der Schleife falsche Antworten erzeugen würde, und der Auto-Vektorisierer kann sich selbst nicht beweisen, dass solche Daten nicht existieren Abhängigkeiten. " [Quelle] (https://msdn.microsoft.com/en-us/library/jj658585.aspx#BKMK_ReasonCode120x) – Tony

Antwort

-3

Ich denke, es zu zahlreichen Zugang aufgrund variabel k const, die den Zweck der SIMD begrenzt als jede Anweisung, die const-Variable k

+2

Das ist eindeutig nicht wahr. – harold

+0

Was ist mit wiederholten Zugriff auf nie wechselnde K in der dritten Funktion? Was ist mit wiederholten Aufrufen von 'a.size()' in der zweiten? : P – hegel5000

2

zu holen hat ich denke, es einige tief internen Compiler-Implementierungsproblem ist, wie In welchem ​​Stadium hat der Auto-Vectorizer "zugeschlagen" und wie ist der Zustand der internen Repräsentation des Codes zu dieser Zeit? Als ich MSVC2017 ausprobierte, funktionierte es mehr im Einklang mit dem, was man erwarten würde. Es Auto-vektorisiert update() und update3(), aber nichtupdate2(), mit der Linie gegeben 501 zum Grund 14, der dokumentiert ist als:

Induktionsvariable nicht lokal ist; oder die obere Grenze ist nicht schleifeninvariant.

Verwandte Themen