Domanda

Sto lavorando su vettorializzazione automatica con GCC. Io non sono in grado di utilizzare intrinseche o attributi a causa di esigenza del cliente. (Non posso ottenere l'input dell'utente per supportare vettorializzazione)

Se le informazioni di allineamento della matrice che può essere vettorializzare è sconosciuta, GCC invoca un pass per 'ciclo delle versioni'. versioning Loop verrà eseguita quando ciclo vettorializzazione è fatto su alberi. Quando un loop viene identificato per essere vectorizable, e il vincolo di allineamento dati o dipendenza dai dati ostacola esso, (perché non possono essere determinati al momento della compilazione), quindi due versioni del ciclo vengono generati. Queste sono le versioni vettorializzate e non vettorializzare del circuito insieme a controlli di runtime per allineamento o dipendenza per controllare quale versione viene eseguito.

La mia domanda è come dobbiamo rispettare l'allineamento? Se ho trovato un ciclo che è vectorizable, non dovrei generare due versioni del circuito a causa di informazioni allineamento mancanti.

Ad esempio. Si consideri il codice seguente

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

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

discarica Albero (opzioni: -fdump-tree-ottimizzato -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>

Al versione 'bb 3' di codice vectorized viene generato. Al codice 'bb 4' senza vettorializzazione viene generato. Questi sono fatti controllando l'allineamento (dichiarazione 'A'). Ora senza utilizzare intrinseche e altri attributi, come dovrei ottenere solo il codice vettorizzati (senza questo controllo allineamento runtime.)

È stato utile?

Soluzione

Se i dati in questione è in corso assegnati in modo statico, quindi è possibile utilizzare l'attributo __align__ che GCC supporta per specificare che dovrebbe essere allineato al limite necessario. Se si assegnano dinamicamente queste matrici, è possibile over-allocare dal valore di allineamento, e quindi urtare il puntatore restituito fino all'allineamento necessario.

È anche possibile utilizzare la funzione posix_memalign() se siete su un sistema che lo supporta. Infine, si noti che malloc() sempre allocare memoria allineato alla dimensione del più grande tipo da incasso, principalmente 8 byte per una doppia. Se non avete bisogno di meglio, allora malloc dovrebbe essere sufficiente.

Modifica : Se si modifica il codice di allocazione per imporre che il check per essere vero (cioè overallocate, come suggerito sopra), il compilatore dovrebbe obbligare, non conditionalizing il codice loop. Se hai bisogno di allineamento a un limite di 8 byte, come sembra, che sarebbe qualcosa di simile a = (a + 7) & ~3;.

Altri suggerimenti

Ottengo solo una versione del ciclo, utilizzando il codice esatto con queste opzioni: gcc -march=core2 -c -O2 -fdump-tree-optimized -ftree-vectorize vec.c

La mia versione di GCC è gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8).

GCC sta facendo qualcosa di intelligente qui. Costringe il a matrici e b da 16 byte allineati. E non lo fa a c, presumibilmente perché c non viene mai usato in un ciclo vectorizable.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top