Pregunta

Estoy trabajando en la vectorización automática con GCC. No estoy en condiciones de utilizar los intrínsecos o atributos debido a los requerimientos del cliente. (No puedo obtener la entrada del usuario para apoyar vectorización)

Si se desconoce la información de alineación de la matriz que se pueden vectorizado, GCC invoca un pase de 'bucle de versiones'. versiones bucle se lleva a cabo cuando la vectorización de bucle se realiza en los árboles. Cuando se identifica un bucle para ser vectorizable, y la restricción en la alineación de los datos o la dependencia de datos está obstaculizando IT, (debido a que no se pueden determinar en tiempo de compilación), entonces se generarán dos versiones del bucle. Estas son las versiones vectorizadas y no vectorizadas del bucle, junto con los controles de tiempo de ejecución para la alineación o la dependencia para controlar qué versión se ejecuta.

Mi pregunta es cómo tenemos que hacer cumplir la alineación? Si he hallado un bucle que es vectorizable, no debería generar dos versiones del bucle debido a la falta de información alineación.

Por ejemplo. Consideremos el siguiente código

short a[15]; short b[15]; short c[15];
int i;

void foo()
{
    for (i=0; i<15; i++)
    {
      a[i] = b[i] ;
    }
}

volcado árbol (opciones: optimizado -fdump-árbol--ftree-vectorize)

<SNIP>
     vector short int * vect_pa.49;
     vector short int * vect_pb.42;
     vector short int * vect_pa.35;
     vector short int * vect_pb.30;

    bb 2>:
     vect_pb.30 = (vector short int *) &b;
     vect_pa.35 = (vector short int *) &a;
     if (((signed char) vect_pa.35 | (signed char) vect_pb.30) & 3 == 0)    ;; <== (A)
       goto <bb 3>;
     else
       goto <bb 4>;

    bb 3>:
</SNIP>

En la versión 'bb 3' de código vectorizado se genera. En 'BB 4' código sin vectorización se genera. Estos se realizan mediante la comprobación de la alineación (comunicado 'A'). Ahora sin necesidad de utilizar otros atributos intrínsecos y, cómo debería obtener sólo el código vectorizado (sin esta comprobación de la alineación en tiempo de ejecución.)

¿Fue útil?

Solución

Si los datos en cuestión se están asignando de forma estática, a continuación, puede utilizar el atributo __align__ que soporta GCC para especificar que debe estar alineado con el límite necesario. Si se están asignando dinámicamente estas matrices, puede sobreasigne por el valor de alineación, y luego volcar el puntero devuelto hasta la alineación que necesita.

También puede utilizar la función posix_memalign() si estás en un sistema que la sustenta. Por último, cabe destacar que malloc() siempre va a asignar memoria alineado con el tamaño del mayor tipo incorporado, generalmente de 8 bytes para un doble. Si no se necesita más que eso, entonces malloc debería ser suficiente.

Editar : Si modifica el código de asignación para obligar a que el registro para ser verdad (es decir overallocate, como se sugirió anteriormente), el compilador debe obligar al no conditionalizing el código de bucle. Si usted necesita la alineación a un límite de 8 bytes, como parece, eso sería algo así como a = (a + 7) & ~3;.

Otros consejos

consigo solamente una versión del bucle, utilizando el código exactamente a estas opciones: gcc -march=core2 -c -O2 -fdump-tree-optimized -ftree-vectorize vec.c

Mi versión de GCC es gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8).

GCC está haciendo algo inteligente aquí. Obliga al a matrices y b a ser de 16 bytes alineados. No hace que a c, presumiblemente porque c nunca se utiliza en un bucle vectorizable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top