Vai git ou ifort compiladores usar com sabedoria as instruções SIMD quando soma o produto de duas matrizes?
-
22-12-2019 - |
Pergunta
Eu tenho um pouco de código escrito com numpy, e estou pensando em migrar para o Fortran para um melhor desempenho.
Uma operação que eu faço muitas vezes é somar o elemento de sabedoria, de produto de duas matrizes:
sum(A*B)
Parece multiplicação-adição instruções iria ajudar com isso.Meu atual processador não der suporte a estas instruções, então eu não posso testar coisas ainda.No entanto, eu pode atualizar para um novo processador que suporta FMA3 (um Intel Haswell processador).
Alguém sabe se compilar o programa com "-march=native" (ou o ifort equivalente) será suficiente para obter o compilador (ou git ou ifort) para usar com sabedoria as instruções SIMD para otimizar o código, ou você acha que eu vou ter para o bebê os compiladores ou código?
Solução 3
Graças a Xiaolei Zhu a dica, agora eu sei que o git irá utilizar multiplicação-adição para otimizar sum(A*B)
.Por exemplo, com este código:
programa de teste de implicit none
real, dimension(7) ::a, b
um = (/ 2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0 /)
b = (/ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0 /)
print *, soma(a*b)
endprogram
Eu posso compilar com f95 sum.f95 -o sum -O3 -march=core-avx2
, e objdump -d sum | grep vfmadd
apresenta
40088b:c4 e2 71 99 44 24 30 vfmadd132ss 0x30(%rsp),%xmm1,%xmm0
400892:c4 e2 69 b9 44 24 34 vfmadd231ss 0x34(%rsp),%xmm2,%xmm0
400899:c4 e2 61 b9 44 24 38 vfmadd231ss 0x38(%rsp),%xmm3,%xmm0
4008a0:c4 e2 59 b9 44 24 3c vfmadd231ss 0x3c(%rsp),%xmm4,%xmm0
4008a7:c4 e2 51 b9 44 24 40 vfmadd231ss 0x40(%rsp),%xmm5,%xmm0
4008ae:c4 e2 49 b9 44 24 44 vfmadd231ss 0x44(%rsp),%xmm6,%xmm0
4008b5:c4 e2 41 b9 44 24 48 vfmadd231ss 0x48(%rsp),%xmm7,%xmm0
Assim git que conduzia o laço e colocar em 7 de multiplicação-adição de instruções.Se eu criar maior, de forma aleatória, matrizes multidimensionais, ainda vejo vfmadd231ss pop-up uma vez (para não desenrolar o laço).
Outras dicas
Se você usar -march=native
em uma máquina com SIMD, o compilador deve gerar instruções SIMD, embora eu sempre usei -xHost
bandeira com ifort.
Mas eu não tenho certeza de como fazê-los fazê-lo "sabiamente".Meu sentimento é de que em -O3
nível ifort e git ambos tendem a ser excessivamente agressivo na vetorização (isto é, usam o SIMD funcionalidade mais frequentemente do que deveriam).Muitas vezes eu preciso desligar o vetorização para obter o código mais eficiente.Isso, claro, pode ou não ser verdadeiro para você.
Normalmente, será melhor usar o vetor de bibliotecas, que são otimizadas para esta tarefa.Você pode usar vdmul
em MKL ou gsl_vector_mul
na GSL para fazer isso.
Usando -march=NEWARCH
vai resultar em um código atento para a arquitetura NEWARCH mas não é possível executar uma versão anterior de arquitetura.Você pode usar o -mtune=NEWARCH
bandeira onde NEWARCH é a arquitetura do seu novo processador.Isto irá gerar o código atento para a nova arquitetura, mas ainda executável no antigo.Desde que você ainda não tem a nova máquina, -mtune
é provavelmente o que você precisa no momento.
Com ifort você pode usar vetorização relatório de bandeiras para mostrar que faz parte do programa foi vetorizados.Por exemplo, ifort
bandeira -vec-report=1
vai dar-lhe essa informação durante a compilação.Eu tenho certeza que não vai ser um equivalente sinalizador no git.
fortran versões onde sum(a*b)
deu melhor vetorização de dot_product(a,b)
são longos obsoletos.O código de você mostrar é a utilização de série AVX2 fma instruções.
Na implementação de dot_product
sem indiretas de indexação ou outras complicações (um loop simples por si só), fma, provavelmente, será mais lento do que a combinação de simd paralelo multiplicar e adicionar instruções, porque a multiplicar pode ser feito fora da latência do caminho crítico.git uso do paralelo simd fma para dot_product pode ser bastante eficaz em casos mais complicados.
Você vai precisar de um -O2 -ftree-vectorize -ffast-math -march=native or -O3 -ffast-math -march=native
(bem como o adequado vetor de comprimento) para vectorize isso, e git pode falhar para vectorize dentro de um OpenMP região paralela.
git 4.9 parece ter descartado a opção -ftree-vectorizer-verbose.-fdump-árvore-vect grava os detalhes de vetorização passa para um .vect arquivo, com diferentes nomes escolhidos para diferentes grandes gcc versões.