2012-07-16 15 views
11

He estado luchando con la vectorización de una aplicación en particular desde hace algún tiempo y lo he intentado todo. Desde la autovectorización hasta los intrínsecos SSE codificados a mano. Pero de alguna manera no puedo obtener aceleración en mi aplicación basada en esténciles.No se puede detectar por qué el siguiente fragmento de código no se ha vectorizado

El siguiente es un fragmento de mi código actual, que he vectorizado utilizando intrínsecamente SSE. Cuando compilo (Intel icc) usando -vec-report3 obtengo este mensaje constantemente:
observación: el bucle no se vectorizó: la declaración no se puede vectorizar.

#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); 

    } 

Me estoy perdiendo algo fundamental? Dado que el mensaje no explica en detalle por qué no se puede vectorizar, me resulta difícil determinar el cuello de botella.

ACTUALIZACIÓN: Después de una cuidadosa consideración de las sugerencias, ajusté el código de la siguiente manera. Pensé que era mejor desglosarlo aún más para identificar las afirmaciones que realmente son responsables de la dependencia del vector.

//#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 

    } 

Cuando compilo (CPI) el código anterior sin #pragma ivdep me sale el siguiente mensaje:

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. 

Cuando compilo (ICC) con el #pragma ivdep, me sale el siguiente mensaje:

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

¿Por qué hay una dependencia sugerida para la línea 196? ¿Cómo puedo eliminar la dependencia del vector sugerida?

+0

Simplifique el constructo 'for' mediante la precomputación del valor final y el número de bucles. –

+0

No puede vectorizarlo porque ya lo ha vectorizado. No obtiene ninguna aceleración porque su relación de computación/acceso a la memoria es demasiado baja. – Mysticial

+0

No fue la alineación que fue mi primer pensamiento (Mysticial me corrigió), pero definitivamente vale la pena comenzar por simplificar las expresiones para los desplazamientos de la matriz. –

Respuesta

2

El problema es que estás tratando de utilizar la auto-vectorización junto con el código vectorizado a mano. El compilador dice que la línea no se puede vectorizar porque no se puede vectorizar una función vectorial.

O permite que el compilador vectorice automáticamente, o deshabilite la vectorización automática y vectorice manualmente su código. Como ya se comentó, el vectorizador automático calculará la rentabilidad de vectorización: verifica si vale la pena o no vectorizar su código.

Cuestiones relacionadas