FMA3 no GCC: como ativar

Eu tenho um i5-4250U que possui AVX2 e FMA3. Estou testando algum código denso de multiplicação de matrizes no GCC 4.8.1 no Linux, que escrevi. Abaixo está uma lista de três maneiras diferentes de compilar.

SSE2:     gcc matrix.cpp -o matrix_gcc -O3 -msse2 -fopenmp
AVX:      gcc matrix.cpp -o matrix_gcc -O3 -mavx  -fopenmp
AVX2+FMA: gcc matrix.cpp -o matrix_gcc -O3 -march=native -fopenmp -ffast-math

As versões SSE2 e AVX são claramente diferentes em desempenho. No entanto, o AVX2 + FMA não é melhor que a versão AVX. Eu não entendo isso. Recebo mais de 80% dos picos de falhas da CPU, supondo que não haja FMA, mas acho que devo conseguir muito melhor com o FMA. A multiplicação de matrizes deve se beneficiar diretamente das FMA. Eu sou esse, finalmente fazendo oito produtos de ponto ao mesmo tempo no AVX. Quando eu checomarch=native dá:

cc -march=native -E -v - </dev/null 2>&1 | grep cc1 | grep fma 
...-march=core-avx2 -mavx -mavx2 -mfma -mno-fma4 -msse4.2 -msse4.1 ...

Para ver que está ativado (apenas para ter certeza de que adicionei-mfma mas não faz diferença).ffast-math deve permitir um modelo de ponto flutuante relaxadoComo usar as instruções FMA (Fused Multiply-Add) com SSE / AVX

Editar:

Com base nos comentários de Mysticial, fui em frente e usei _mm256_fmadd_ps e agora a versão AVX2 + FMA é mais rápida.Não sei por que o compilador não fará isso por mim. Agora estou recebendo cerca de 80 GFLOPS (110% dos picos de flops sem FMA) para mais de 1000x1000 matrizes. Caso alguém não confie no meu cálculo de pico no flop, aqui está o que eu fiz.

peak flops (no FMA) = frequency * simd_width * ILP * cores
                    = 2.3GHZ    * 8          * 2   * 2     =  73.2 GFLOPS
peak flops (with FMA) = 2 * peak flops (no FMA)            = 146.2 GFLOPS

Minha CPU no modo turbo ao usar os dois núcleos é de 2,3 GHz. Eu recebo 2 para ILP porque o Ivy Bridge pode fazer uma multiplicação de AVX e uma adição de AVX ao mesmo tempo (e desenrolei o loop várias vezes para garantir isso).

Estou recebendo apenas 55% dos picos de flops (com FMA). Não sei por que, mas pelo menos estou vendo algo agora.

Um efeito colateral é que agora recebo um pequeno erro ao comparar com um algoritmo simples de multiplicação de matrizes em que confio. Eu acho que isso se deve ao fato de que as FMA só têm um modo de arredondamento em vez do que normalmente seriam dois (o que ironicamente quebra as regras de ponto flutuante IEEE, embora provavelmente seja melhor).

Editar:

Alguém precisa refazerComo alcanço o máximo teórico de 4 FLOPs por ciclo? mas faça 8 FLOPS de ponto flutuante duplo por ciclo com o Haswell.

Editar

Na verdade, Mysticial atualizou seu projeto para apoiar o FMA3 (veja sua resposta no link acima). Eu executei o código dele no Windows8 com o MSVC2012 (porque a versão do Linux não compilava com o suporte às FMA). Aqui estão os resultados.

Testing AVX Mul + Add:
Seconds = 22.7417
FP Ops  = 768000000000
FLOPs   = 3.37705e+010
sum = 17.8122

Testing FMA3 FMA:
Seconds = 22.1389
FP Ops  = 1536000000000
FLOPs   = 6.938e+010
sum = 333.309

São 69,38 GFLOPS para FMA3 para ponto flutuante duplo. Para um ponto flutuante único, eu preciso dobrá-lo para que seja 138,76 SP GFLOPS. Calculo que meu pico é 146.2 SP GFLOPS.Isso é 95% do pico! Em outras palavras, eu devo melhorar meu código GEMM um pouco (embora já seja um pouco mais rápido que o Eigen).

questionAnswers(2)

yourAnswerToTheQuestion