Pergunta

Por que é obrigatório o uso de -ffast-math com o g++ para alcançar a vetorização de loops usando doubles?Não gosto -ffast-math porque eu não quero perder precisão.

Foi útil?

Solução

Você não necessariamente perder precisão com -ffast-math.Ele só afeta o tratamento de NaN, Inf etc.e a ordem em que as operações são executadas.

Se você tem um determinado trecho de código onde você não deseja GCC para reordenar ou simplificar os cálculos, você pode marcar as variáveis como sendo utilizados através de uma asm instrução.

Por exemplo, o código a seguir executa uma operação de arredondamento f.No entanto, os dois f += g e f -= g as operações são susceptíveis de obter optimizado para longe pelo gcc:

static double moo(double f, double g)                                      
{                                                                          
    g *= 4503599627370496.0; // 2 ** 52                                    
    f += g;                                                                
    f -= g;                                                                
    return f;                                                            
}                                                                     

No x86_64, você pode usar este asm declaração para instruir o GCC não para executar a otimização:

static double moo(double f, double g)                                      
{                                                                          
    g *= 4503599627370496.0; // 2 ** 52                                    
    f += g;                                                                
    __asm__("" : "+x" (f));
    f -= g;
    return f;
}

Você terá de se adaptar a esta para cada arquitetura, infelizmente.Em PowerPC, use +f em vez de +x.

Outras dicas

Muito provavelmente porque a vetorização significa que você pode ter resultados diferentes ou pode significar que sente falta de sinais/exceções de ponto flutuante.

Se você estiver compilando para o X86 de 32 bits, o GCC e o G ++ padrão de usar o X87 para matemática de ponto flutuante, em 64 bits, eles são inadimplentes para o SSE, no entanto, o x87 pode e produzirá valores diferentes para o mesmo cálculo, por isso é improvável G ++ considerará a vetorização se não puder garantir que você obterá os mesmos resultados, a menos que use -ffast-math Ou algumas das bandeiras que ela liga.

Basicamente, tudo se resume ao ambiente de ponto flutuante para o código vetorizado pode não ser o mesmo que o código não vetorizado, às vezes de maneiras importantes, se as diferenças não importam para você, algo como

-fno-math-errno -fno-trapping-math -fno-signaling-nans -fno-rounding-math

Mas, primeiro, procure essas opções e verifique se elas não afetarão a correção do seu programa. -ffinite-math-only pode ajudar também

Porque -ffast-math permite Operands reordenando que permite que muitos código sejam vetorizados.

Por exemplo, para calcular isso

sum = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + … a[99]

o compilador é requeridos Para fazer as adições sequencialmente sem -ffast-math, porque a matemática de ponto flutuante não é comutativo nem associativo.

Esse é o mesmo motivo Por que os compiladores não podem otimizar a*a*a*a*a*a para (a*a*a)*(a*a*a) sem -ffast-math

Isso significa que nenhuma vetorização disponível, a menos que você tenha um vetor horizontal muito eficiente adicionado.

No entanto, se -ffast-math está ativado, a expressão pode ser calculada assim (Olhe para A7. Auto-Vectorization)

sum0 = a[0] + a[4] + a[ 8] + … a[96]
sum1 = a[1] + a[5] + a[ 9] + … a[97]
sum2 = a[2] + a[6] + a[10] + … a[98]
sum3 = a[3] + a[7] + a[11] + … a[99]
sum’ = sum0 + sum1 + sum2 + sum3

Agora, o compilador pode vetorizá -lo facilmente adicionando cada coluna em paralelo e depois fazer um add horizontal no final

Faz sum’ == sum? Somente se (a[0]+a[4]+…) + (a[1]+a[5]+…) + (a[2]+a[6]+…) + ([a[3]+a[7]+…) == a[0] + a[1] + a[2] + … Isso se mantém sob associatividade, que os flutuos não aderem, o tempo todo. Especificação /fp:fast Permite que o compilador transforme seu código para executar mais rápido - até 4 vezes mais rápido, para este cálculo simples.

Você prefere rápido ou preciso? - A7. Vetorização automática

Pode ser ativado pelo -fassociative-math Bandeira no GCC

Outras leituras

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