Pergunta

Eu estou trabalhando em auto vetorização com GCC. Não estou em posição de intrínsecos uso ou atributos devido à exigência do cliente. (Eu não posso começar a entrada do usuário para vetorização de suporte)

Se a informação de alinhamento da matriz que pode ser vetorizado é desconhecida, GCC invoca um passe para 'loop de controle de versão'. Loop de controle de versão será executada quando vetorização loop é feito em árvores. Quando um circuito é identificado como sendo vectorizable, e a restrição no alinhamento de dados ou dependência de dados é impedi-la, (porque não pode ser determinado em tempo de compilação), em seguida, duas versões do ciclo irá ser gerado. Estas são as versões vectorizada e não-Vectorized do loop juntamente com controlos de tempo de execução para o alinhamento ou dependência a versão de controlo que é executado.

A minha pergunta é como temos que fazer valer o alinhamento? Se eu ter encontrado um loop que é vectorizable, não deve gerar duas versões do circuito por causa da falta de informação sobre o alinhamento.

Por exemplo. Considere o código abaixo

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

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

despejo Tree (opções:--fdump-árvore otimizado -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>

No 'bb 3' versão do código vetorizado é gerado. No 'bb 4' código sem vetorização é gerado. Estas são feitas por verificar o alinhamento (declaração 'A'). Agora sem usar intrínsecos e outros atributos, como devo começar apenas o código vectorized (sem esta verificação de alinhamento de tempo de execução.)

Foi útil?

Solução

Se os dados em questão está sendo alocado estaticamente, então você pode usar o atributo __align__ que os apoios do CCG para especificar que ele deve ser alinhado com o limite necessário. Se você está alocando dinamicamente essas matrizes, você pode over-alocar pelo valor de alinhamento, e depois bater o ponteiro retornado até o alinhamento que você precisa.

Você também pode usar a função posix_memalign() se você estiver em um sistema que o suporta. Finalmente, nota de memória que malloc() sempre alocar alinhado com o tamanho do maior tipo built-in, geralmente 8 bytes para um duplo. Se você não precisa de mais do que isso, então malloc deve bastar.

Editar : Se você modificar o código de alocação para forçar que o check para ser verdade (ou seja overallocate, como sugerido acima), o compilador deve obrigar por não conditionalizing o código de loop. Se você precisava de alinhamento a um limite de 8 bytes, como parece, que seria algo como a = (a + 7) & ~3;.

Outras dicas

eu recebo apenas uma versão do loop, utilizando o seu código exato com estas opções: gcc -march=core2 -c -O2 -fdump-tree-optimized -ftree-vectorize vec.c

A minha versão do GCC é gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8).

GCC está fazendo algo inteligente aqui. Isso força o a matrizes e b para ser de 16 bytes alinhados. Ele não faz isso para c, presumivelmente porque c nunca é usado em um loop vectorizable.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top