2012-07-16 9 views
11

Od pewnego czasu zmagam się z wektoryzacją konkretnej aplikacji i próbowałem wszystkiego. Od autovectorization, po ręcznie kodowane SSE. Ale jakoś nie jestem w stanie uzyskać przyspieszenia w mojej aplikacji opartej na szablonie.Nie można wykryć, dlaczego następujący fragment kodu nie był wektoryzowany

Poniżej znajduje się fragment mojego obecnego kodu, który wektoryzowałem za pomocą wewnętrznej samoistości SSE. Podczas kompilacji (Intel icc) przy użyciu -vec-report3 ciągle otrzymuję komunikat:
uwaga: pętla nie była wektoryzowana: instrukcja nie może być wektoryzowana.

#pragma ivdep 
    for (i = STENCIL; i < z - STENCIL; i+=4) 
    { 
    it = it2 + i; 

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k])),X4_i); //loop was not vectorized: statement cannot be vectorized 
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k])),X3_i); 
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k])),X2_i); 
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j +k*it_k])),X1_i); 

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)), _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i)); 

    _mm_store_ps(&tmp2[i],tmp6); 

    } 

Am I czegoś brakuje kluczową? Ponieważ komunikat nie wyjaśnia, dlaczego nie można go wektoryzować, trudno mi stwierdzić wąskie gardło.

AKTUALIZACJA: Po dokładnym rozważeniu sugestii, zmodyfikowałem kod w następujący sposób. Pomyślałem, że najlepiej jest rozbić to jeszcze bardziej, aby zidentyfikować stwierdzenia, które faktycznie są odpowiedzialne za uzależnienie wektorowe.

//#pragma ivdep 
    for (i = STENCIL; i < z - STENCIL; i+=4) 
    { 
    it = it2 + i; 
    __m128 center = _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i); 

    u_j4 = _mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]); //Line 180 
    u_j3 = _mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]); 
    u_j2 = _mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]); 
    u_j1 = _mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]); 
    u_j8 = _mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k]); 
    u_j7 = _mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k]); 
    u_j6 = _mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k]); 
    u_j5 = _mm_load_ps(&p2[i+j*it_j+it_j +k*it_k]); 

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(u_j4,u_j8),X4_i); 
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(u_j3,u_j7),X3_i); 
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(u_j2,u_j6),X2_i); 
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(u_j1,u_j5),X1_i); 

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)); 
    __m128 tmp7 = _mm_add_ps(tmp6,center); 

    _mm_store_ps(&tmp2[i],tmp7); //Line 196 

    } 

Kiedy skompilować (ICC) powyższy kod bez #pragma ivdep otrzymuję następujący komunikat:

remark: loop was not vectorized: existence of vector dependence. 
vector dependence: assumed FLOW dependence between tmp2 line 196 and tmp2 line 196. 
vector dependence: assumed ANTI dependence between tmp2 line 196 and tmp2 line 196. 

Kiedy skompilować (ICC) to z #pragma ivdep, pojawia się następujący komunikat:

remark: loop was not vectorized: unsupported data type. //Line 180 

Dlaczego sugerowana jest zależność dla linii 196? Jak mogę wyeliminować sugerowaną zależność wektorową?

+0

Uprość konstrukcje 'for' przez wstępne obliczenie wartości końcowej i liczby pętli. –

+0

Nie można go wektoryzować, ponieważ już to wektoryzowałeś. Nie uzyskujesz żadnego przyspieszenia, ponieważ twój współczynnik obliczeń/dostępu do pamięci jest zbyt niski. – Mysticial

+0

To nie jest wyrównanie, które było moją pierwszą myślą (naprawił mnie Mysticial), ale zdecydowanie warto zacząć od uproszczenia wyrażeń dla przesunięć tablicy. –

Odpowiedz

2

Problem polega na tym, że próbujesz użyć automatycznego wektoryzacji razem z ręcznie wektoryzowanym kodem. Kompilator mówi, że linia nie może być wektoryzowana, ponieważ nie można wektoryzować funkcji wektorowej.

Pozwolić kompilatorowi na jego automatyczne wektorowanie lub wyłączyć automatyczną wektoryzację i ręcznie wektoryzować kod. Jak już zauważyliśmy, automatyczny vectorizer obliczy opłacalność wektoryzacji: sprawdza, czy warto lub nie wektoryzować swojego kodu.

Powiązane problemy