• Nenhum resultado encontrado

B.4 Modelo roofline para a GPU Tesla K40

5.3 Validação de resultados

As figuras 5.1 e 5.2 mostram o resultado do empilhamento CMP do dado Simple- synthetic utilizando-se a CPU e a GPU, respectivamente. Apesar da semelhança, estas imagens possuem diferenças sutis em alguns dos pontos computados.

A Figura 5.3 é a diferença entre as figuras do empilhamento. Essa figura exibe uma diferença, mas essa diferença é muito sutil para ser vista a olho nu com essa resolução. No entanto, o histograma da Figura 5.3 mostra que essas diferenças ocorrem com frequências muito mais altas em bits menos significativos do que em bits mais significativos. Com o uso de uma ferramenta chamada suximage, pode-se ver que a diferença gerada por esses bits é de no máximo 0.0003884.

A primeira hipótese para tais diferenças é que elas são ocasionadas por erros numéri- cos devido a diferentes implementações do padrão IEEE-754-2008 [2]. Para avaliar essa hipótese, foram realizados dois experimentos que estão descritos abaixo:

• Experimento 1: Simplesmente usar ponto flutuante de precisão dupla. Dessa forma, os resultados das implementações se mostraram iguais.

• Experimento 2: Localizar os pontos da imagem gerada que são diferentes e depois analisar qual é a causa dessa diferença.

0 1 2 3 4 5 100 200 300 400 -1 0 1 2 3 4 x10 -4

Figura 5.1: Empilhamento reali- zado na CPU. 0 1 2 3 4 5 100 200 300 400 -1 0 1 2 3 4 x10 -4

Figura 5.2: Empilhamento reali- zado na GPU. 0 1 2 3 4 5 100 200 300 400 -4 -3 -2 -1 0 1 2 3 4 x10 -4 0 5 10 15 20 25 30 35 40 45 50 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Bits Porcentagem de pontos errados

Figura 5.3: Diferença entre as Figuras 5.1 e 5.2; a primeira imagem mostra a imagem resultante da subtração da imagem 5.1 e 5.2 e a segunda é o histograma da diferença.

O experimento 1 fornece fortes evidências de que a diferença observada é oriunda de erro numérico, mas ainda assim não fornece informações suficientes para concluir quais operações estão gerando tal erro. Os resultados do experimento 2, por sua vez, indicam que a diferença encontrada é oriunda do trecho de código que implementa o algoritmo 2. Neste trecho de código tem-se as seguintes operações:

1. t2 *= t2

2. t2 += C * (hx*hx + hy*hy) 3. sqrt(t2)

Para os parâmetros abaixo, a função obtém resultados diferentes na terceira operação quando se compara a execução em GPU e CPU. Essa diferença é bem pequena, observando os bits que formam o float resultante da terceira operação a diferença é somente no bit menos significativo.

• t2= 3.17800021171569824219. • C= 0.00000044702971990773. • hx= 0.000000.

• hy= -300.000000.

Para descobrir o motivo de tal diferença, foi realizada uma implementação dessas operações usando a MPFR (Multiple-Precision Binary Floating-Point Library) [18], o que permitiu testar vários padrões de arredondamento definidos pelo padrão da IEEE. Comparando-se os vários métodos de arredondamento, observa-se que a diferença nessas operações se deve às políticas de arredondamento diferentes.

A inspeção do código gerado pelo compilador OpenCL revela que a instrução emitida para realizar a operação de raiz quadrada é sqrt.approx.f32, que implementa a raiz qua- drada com um método de arredondamento diferente dos definidos em IEEE-754-2008 [2], como os resultados experimentais mostraram.

Porém, o experimento com a MPFR não é suficiente para dizer que todos os pontos são diferentes por causa de um erro numérico dessa forma. Como o experimento usando double não mostra diferença, pode-se levantar três hipóteses para explicar as diferenças quando se usa float :

1. Existe um bug na implementação OpenCL que não mostra nenhum efeito quando se usa double.

2. As diferenças são geradas devido a um erro numérico. 3. Todas as hipóteses acima são verdadeiras.

Dessa forma, um jeito trivial de se provar qual das hipóteses é verdadeira é provar que as duas implementações são equivalentes, Se isso for verdade, então, a hipótese 1 é falsa e a 3 é falsa, portanto, a única explicação é a hipótese 2. Para isso, basta realizar a demonstração que as implementações OpenMP e OpenCL são equivalentes. Esta prova não vai ser mostrada aqui, já que é uma prova relativamente grande. (A prova pode ser vista em toda a sua completude no Apêndice A). Como a demonstração do Apêndice A mostra que as duas implementações são equivalentes, a hipótese 2 é verdade, então as diferenças de computação de uma implementação para outra é somente devido a erro numérico.

1 f l o a t t2d = t i m e 2 d ( A , B , C , t0 , m0x , m0y , mx , my , hx , hy ) ;

2 int it = (int) ( t2d * idt ) ;

3 if ( it - tau >= 0 && it + tau +1 < tr - > ns ) {

5 int k = it + j - tau ; 6 f l o a t v = i n t e r p o l _ l i n e a r ( k , k +1 , 7 tr - > d a t a [ k ] , tr - > d a t a [ k +1] , 8 t2d * idt + j - tau ) ; 9 num [ j ] += v ; 10 den [ j ] += v * v ; 11 _ s t a c k += v ; 12 } 13 M ++; 14 } e l s e if (++ sk i p == 2) { 15 r e t u r n 0; 16 } 17 }

Código 5.1: Trecho do código que calcula semblance para o CMP e CRS.

O próximo passo é provar que a diferença numérica não afeta a imagem gerada do ponto de vista geofísico. Para isso, uma análise das operações no cálculo da semblance tem que ser realizada. Pelo experimento 2 e pela prova do Apêndice A, pode-se concluir que existe apenas um ponto na execução em que temos diferença entre a GPU e a CPU, esse ponto é o trecho que implementa algoritmo 2. Logo, basta provar que para um erro e que é resultante dessa função, o resultado da semblance vai ser equivalente. Seja t2d + e o resultado na GPU da função que implementa o algoritmo 2, onde:

• t2d: resultado da função que implementa o algoritmo 2 na CPU. • e: erro numérico.

Primeiro vamos provar para e > 0: Logo na linha 2 do trecho de código 5.1:

it = b(e + t2d) ∗ idtc. (5.1)

pode-se reescrever a Equação 5.1 como:

it = be ∗ idt + t2d ∗ idtc. (5.2)

No caso que be∗idt+t2d∗idtc ≤ t2d∗idt, temos que be∗idt+t2d∗idtc ≤ e∗idt+t2d∗idt. Logo, e ∗ idt < 1, e pode-se escrever a equação 5.2 como:

it = bt2d ∗ idtc (5.3)

Neste caso o erro e não influência na escolha da posição bkc. Dessa forma, basta mostrar que a interpolação linear ainda devolve um número entre data[bkc+1] e data[bkc]. Com o objetivo de tornar os próximos passos mais claros, o vetor data será chamado de

d. Da chamada de interpol_linear supondo que e = 0, temos a seguinte Equação: v = (d[bkc + 1] − d[bkc]) ∗ (t2d ∗ idt + j − tau − k) + d[bkc] (5.4) Como k = it + j − tau logo:

v = (d[bkc + 1] − d[bkc]) ∗ (t2d ∗ idt − bt2d ∗ idtc) + d[bkc]. (5.5) Seja t2d ∗ idt − bt2d ∗ idtc = α, logo 0 ≤ α < 1, então tem-se:

v = (d[bkc + 1] − d[bkc]) ∗ α + d[bkc] (5.6) Se α = 0, logo v = d[bkc]. Agora, para limα→1(d[bkc + 1] − d[bkc]) ∗ α + d[bkc], tem-se

v = d[bkc + 1].

Agora, basta provar que para um erro e que existe um β que respeita as mesmas restrições de α. Então se reescreve a equação 5.5 como:

v = (d[bkc + 1] − d[bkc]) ∗ ((t2d + e) ∗ idt − b(t2d + e) ∗ idtc) + d[bkc]. (5.7) Seja β = (t2d + e) ∗ idt − b(t2d + e) ∗ idtc , logo 0 ≤ β < 1, então tem-se:

v = (d[bkc + 1] − d[bkc]) ∗ β + d[bkc] (5.8) Se β = 0, logo v = d[bkc]. Agora, para limβ→1(d[bkc + 1] − d[bkc]) ∗ β + d[bkc], tem-se

v = d[bkc + 1].

Logo, neste caso o erro numérico não influência na qualidade do empilhamento, já que as amostras olhadas dos traços são as mesmas.

Agora, a prova da influência do erro quando o be ∗ idt + t2d ∗ idtc > t2d ∗ idt: neste caso, em primeiro lugar temos que provar a influência sobre k, já que agora temos que k = b(e + t2d) ∗ idtc + j − tau, vamos avaliar o erro que k sofre, para isso vamos determinar um limite superior para esse erro; portanto, pela definição de k, temos que o erro é de no máximo e ∗ idt.

Como os resultados experimentais mostram que |e| é menor que 10−10 e temos da implementação que idt é no máximo 106, o erro de k é menor que 10−4; isso implica que,

no pior dos casos, a janela será movida uma amostra para cima ou uma amostra para baixo. A partir disso, temos como corolário da prova anterior que a interpol_linear vai devolver um número entre as duas amostras consideradas.

Agora vamos provar para e < 0 :

Como idt > 0, logo e ∗ idt < 0. Então temos só o seguinte caso:

be ∗ idt + t2d ∗ idtc ≤ t2d ∗ idt (5.9) A influência sobre a posição de k, já foi discutida no caso de e < 0 e para esse caso o pior cenário que temos é a janela do cálculo da semblance seja deslocada uma posição para baixo. Agora o acesso na interpolação linear já foi provado para o caso mostrado na

equação 5.9.

Não obstante, tanto as operações usando as políticas de arredondamento, definida em IEEE-754-2008 [2], quanto as operações que não seguem o padrão estão limitadas pela representação binária que é feita pelo tipo float. Essa limitação se da em dois aspec- tos: primeiro o número de bits e segundo pela própria forma de representação em si. Como o float normalmente tem tamanho de 32 bits, logo esse fato está limitado tanto o programa OpenMP e o OpenCL independente do método de arredondamento usado. Dessa forma, então temos que os dois programas são apenas aproximações, mesmo que tais aproximações não tenham diferenças práticas de uma solução onde tudo possa ser representado como números reais. Dito isso, um experimento foi feito com o objetivo de ter uma estimativa do erro das duas implementações de uma em que se consiga usar números reais para isso utilizamos a MPFR, que nos permite o uso de representações de precisão arbitrária.

Com a MPFR criamos uma implementação que usa floats de 1024 bits e assim tentamos nos aproximar mais de um número real, atacando o primeiro problema de representação em binário. Dessa forma, têm-se que o erro das duas implementações em relação a imple- mentação de 1024 bits é quase o mesmo; como pode-se ver nos histogramas mostrados na Figura 5.4, o objetivo desse experimento era só provar o que já era esperado: que as duas implementações teriam diferenças comparadas com uma implementação com mais bits de precisão. Como a diferença das duas em relação a com MPFR é quase nenhuma, as duas implementações para todos os fins práticos são equivalentes. Tais resultados podem ser estendidos tanto para o CRS, quanto para a estimação dos parâmetros da migração CRP em tempo, já que o cálculo envolvido é o mesmo.

0 5 10 15 20 25 30 35 40 45 50 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Bits Porcentagem de pontos errados

0 5 10 15 20 25 30 35 40 45 50 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Bits Porcentagem de pontos errados

Figura 5.4: O histograma à esquerda representa a diferença entre a GPU e a implementa- ção com MPFR de 1024 bits. O histograma à direita representa a diferença entre a CPU e a implementação usando MPFR de 1024 bits.

Documentos relacionados