Técnicas avançadas de utilização de GPU e CUDA

411 views
285 views

Published on

Palestra ministrada na Semana Sobre Programação Massivamente Paralela - 2014 do Laboratório Nacional de Computação Científica.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
411
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Técnicas avançadas de utilização de GPU e CUDA

  1. 1. Técnicas  avançadas  de  u.lização   de  GPU  e  CUDA   Jose  Ricardo  da  Silva  Junior  
  2. 2. Quem  sou   •  Bacharel  em  Análise  de  Sistemas.   •  Mestre  em  Ciência  da  Computação  na  UFF  (Computação  Gráfica).   •  Doutorando  em  Ciência  da  Computação  na  UFF  (Computação   Gráfica).   •  Doutorado  Sanduíche  University  of  Nebraska   •  Professor  na  Faculdade  CCAA.   •  Colaborador  na  empresa  Nullpointer.   •  Pesquisador  na  área  de  Computação  Gráfica  e  GPGPU.  
  3. 3. Universidade  Federal  Fluminense   Departamento de Computação com 62 professores doutores Laboratórios de ponta em diversas áreas de pesquisa 3  
  4. 4. Nvidia  Center  of  Excelence   4  
  5. 5. Projetos  em  GPU   •  Consórcio  Nacional  de  GRID  em  GPUs   •  Middleware  de  distribuição  de  carga  entre  nós  de   GPUs   •  Middleware  para  o.mização  de  divergências   •  COLATUS:  expansão  de  par[culas  cosmológicas   •  DOMINOES   •  Gerencia  de  versões  em  vídeo  e  imagens   •  Simulação  de  transito  usando  autômatos  finitos   •  Ray-­‐tracing  Hibrido  CUDA/OPENGL/Op.X   5  
  6. 6. Obje=vo   •  Apresentação  de  tópicos  avançados  em  CUDA   através  da  u.lização  de  um  estudo  de  caso.   –  Simulação  de  fluidos  incompressíveis   •  Equação  governante  de  fluidos  de  Navier-­‐ Stokes   ⎛ ∂v ⎞ ρ ⎜ + v.∇v ⎟ = −∇p + ρg + µ∇ 2v ⎝ ∂t ⎠ ∂ρ + ∇.( ρv) = 0 ∂t 6  
  7. 7. Simulação  de  fluidos   •  Métodos  Eulerianos   –  Domínio  da  simulação  discre.zado  em  grade  fixa   –  Computação  efetuada  em  posições  fixa  da  célula   –  O  material  simulado  desloca-­‐se  sobre  a  grade   •  Métodos  Lagrangeanos   –  Material  se  move  com  o  fluido   –  Variáveis  de  campo  calculadas  no  próprio  material   –  Discre.zadas  em  par[culas  ou  malhas   7  
  8. 8. Simulação  de  fluidos   8  
  9. 9. Smoothed  Par=cle  Hydrodynamics   •  Método  Lagrangeano  baseado  em  par[culas   •  Sem  informação  de  conec.vidade   •  Desenvolvido  por  Lucy  e  Gingold/Monaghan  para   simulação  de  fenômenos  astroisicos   •  U.liza  método  de  interpolação  para  integração   de  variáveis  de  campo   9  
  10. 10. Smoothed  Par=cle  Hydrodynamics   •  Fórmula  geral   Aj As (r) = ∑ m j W (r − rj , h) j ρj ∇As (r ) = ∑ j m j 2 Aj ρj ∇ As (r ) = ∑ j m j ∇W ( r − r j , h ) Aj ρj ∇ 2W (r − rj , h) 10  
  11. 11. Simulação  de  Fluído   11  
  12. 12. Estrutura  de  dados   •  U.lização  de  uma  grade  regular  baseada  em   tabela  hash  para  classificação  das  par[culas   –  Grade  com  tamanho  de  célula  com  o  dobro  do   raio  da  par[cula   –  Processamento  de  27  células  em  3D     1 12  
  13. 13. Versão  1   •  Processamento  de  cada  par[cula  do  fluido  em   memória  global.   Classificar   Par[culas   Calcular  Densidade   Calcular  Forças   Internas   Calcular  Forças   Externas   Integrar   ...   while  (!quit){      k_classifyPar.cles<<<>>>();  //  hash  genera.on      cudaThreadSynchronize();      k_calculateDensity<<<>>>();      cudaThreadSynchronize();      k_calculateInternalForces<<<>>>();    cudaThreadSynchronize();      k_calculateExternalForces<<<>>>();    cudaThreadSynchronize();      k_integrate<<<>>>();   }   ...     13  
  14. 14. Versão  1   •  O  acesso  à  memória  global  é  extremamente  lento.   –  Para  cada  par[cula  na  mesma  célula  da  grid,  os  mesmos   dados  dos  vizinhos  são  lidos  várias  vezes  da  memória   global.   •  G80  suporta  86.4Gb/s  de  acesso  à  memoria  global.   –  Ponto  flutuante  de  precisão  simples  =  4  bytes.   –  Neste  caso  não  podemos  carregar  mais  que  86.4  /  4  =  21.6   giga  data  de  ponto  flutuante  simples  por  segundo.   –  Vale  lembrar  que  teoricamente  a  performance  de  uma   G80  é  367  Gflops!   14  
  15. 15. Performance   15  
  16. 16. Versão  2   Área  de  processamento  da  par[cula  2   1 2 Área  de  processamento  da  par[cula  1   Área  comum  entre  par[culas  1  e  2   (memória  compar.lhada)   Supondo  que  cada  célula  armazene  2  parMculas,  qual  a  taxa  de  acesso  à  memória   global  sem  o  compar=lhamento  da  área  comum?   16  
  17. 17. Versão  2   •  U=lização  de  memória  compar=lhada  para  redução  do  acesso  à  memória  global.     U=lizando  memória  global:   Par$cula  1:  9  células:  18  acessos  à  MG.     Par$cula  2:  9  células:  18  acessos  à  MG.   36  acessos       U=lizando  memória  compar=lhada:   Par.cula  1:  5  células:    10  acessos  à  MG.     Par.cula  :  5  células:  10  acessos  à  MG.   28  acessos     Área  comum:  4  células:  8  acessos  à  MG.       17  
  18. 18. Versão  2   •  U.lização  de  memória  compar.lhada:   –  Para  cada  conjunto  de  células,  carregar  dados  de  par[culas  de  células  compar.lhadas   na  memória  compar.lhada,  reu.lizando  os  mesmos  para  várias  par[culas.     void  k_processDensity(){      ...      for  each  cell  in  grid  {          loadPar.cles();          synchronize();          d_processDensity(par.cle);      }      ...   }   •  Obje.vo:  reu.lizar  ao  máximo  dados  na  memória  compar.lhada  (mesmo   que  isso  implique  em  mais  re-­‐processamento!)   18  
  19. 19. Versão  2   •  Algumas  etapas  durante  o  processo  de   simulação  de  fluidos  podem  ser  executadas   em  paralelo  na  GPU.   •  A  arquitetura  FERMI  introduziu  a  possibilidade   de  execução  de  kernels  simultâneos.   –  Verificar  problemas  de  dependência  entre  dados   para  kernels  diferentes.   19  
  20. 20. Versão  3   Classificar   Par[culas   Classificar   Par[culas   Calcular  Densidade   Calcular   Densidade   syncronize()   Calcular  Forças   Internas   Calcular  Forças   Internas   Calcular  Forças   Externas   Calcular  Forças   Externas   Integrar   syncronize()   Integrar   •  Não  existe  dependendência  de  dados  entre  cálculo  de  forças  internas  e   externas.   •  Deve-­‐se  u.lizar  espaços  de  memórias  diferentes  para  o  armazenamento  dos   resultados.   20  
  21. 21. Versão  3   •  A  sincronização  de  kernel  simultâneo  deve  ser   realizada  a  nível  de  CPU.   ...   while  (!quit){      k_classifyPar.cles<<<>>>();  //  hash  genera.on      cudaThreadSynchronize();      k_calculateDensity<<<>>>();      cudaThreadSynchronize();      k_calculateInternalForces<<<>>>();      k_calculateExternalForces<<<>>>();    cudaThreadSynchronize();      k_integrate<<<>>>();   }   ...     21  
  22. 22. Paralelismo  Dinâmico   •  Habilidade  de  geração  de  novos  grids  pela   GPU.   –  Dinâmico.   –  Simultâneamente.   –  Independente.   –  Introduzido  na  arquitetetura  Kepler.   CPU   GPU   CPU   GPU   22  
  23. 23. Paralelismo  Dinâmico   •  Programa  paralelo  simples:   23  
  24. 24. Paralelismo  Dinâmico   •  Programa  paralelo  simples:   24  
  25. 25. Paralelismo  Dinâmico   •  Programa  paralelo  simples:   25  
  26. 26. Paralelismo  Dinâmico   •  Programa  paralelo  simples:   26  
  27. 27. Paralelismo  Dinâmico   •  Possibilidade  de  paralelismo  dinâmico.   27  
  28. 28. Paralelismo  Dinâmico   CPU GPU GPU  as  Co-­‐Processor   CPU GPU Autonomous,  Dynamic  Parallelism   28  
  29. 29. Paralelismo  Dinâmico   Coarse grid Fine grid Dynamic grid Higher Performance Lower Accuracy Lower Performance Higher Accuracy Target performance where accuracy is required 29  
  30. 30. Paralelismo  Dinâmico  (Programação)   int main() { float *data; setup(data); A <<< ... >>> (data); B <<< ... >>> (data); C <<< ... >>> (data); CPU main cudaDeviceSynchronize(); return 0; GPU } A X X <<< ... >>> (data); Y <<< ... >>> (data); Z <<< ... >>> (data); cudaDeviceSynchronize(); B Y do_more_stuff(data); C Z __global__ void B(float *data) { do_stuff(data); } 30  
  31. 31. Paralelismo  Dinâmico  (Decomposição   LU)   LU decomposition (Fermi) memcpy dlaswap<<<>>> dtrsm<<<>>> dgemm<<<>>> next j } dgetrf(N, N) { dgetrf<<<>>> idamax(); dswap(); CPU  is  Free   dgetrf(N, N) { for j=1 to N for i=1 to 64 idamax<<<>>> memcpy dswap<<<>>> memcpy dscal<<<>>> dger<<<>>> next i LU decomposition (Kepler) dscal(); dger(); dlaswap(); dgetrf(N, N) { for j=1 to N for i=1 to 64 idamax<<<>>> dswap<<<>>> dscal<<<>>> dger<<<>>> next i dlaswap<<<>>> dtrsm<<<>>> dgemm<<<>>> next j } synchronize(); } dtrsm(); dgemm(); CPU Code GPU Code CPU Code GPU Code 31  
  32. 32. GPU  Direct   •  Nome  fornecido  à  um  conjunto  de  o.mizações  de   transferência  de  dados  entre  GPU’s.   System Memory CPU GDDR5 Memory GDDR5 Memory GDDR5 Memory GPU1 GPU2 GPU2 GPU1 PCI-e System Memory CPU PCI-e Network Card Server 1 GDDR5 Memory Network Network Card Server 2 32  
  33. 33. GPU  Direct  v1   •  Introduziu  a  capacidade  de  u.lização  da  mesma  memória   page-­‐locked  no  host  pelos  drivers  da  GPU  e  Infiniband.   •  Removeu  a  necessidade  de  cópia  dos  dados  da  GPU  para  CPU.   33  
  34. 34. GPU  Direct  v2   •  Introduziu  a  capacidade  de  acesso  e  transferência  de  dados   entre  memórias  de  GPU  no  mesmo  nó  sem  a  necessidade  de   cópias  para  a  CPU.   34  
  35. 35. GPU  Direct  v3   •  Introduziu  a  capacidade  de  transferência  de  dados  entre  duas  GPU’s  em  nós   diferentes  u.lizando  rede  Infiniband,  sem  necessidade  de  u.lização  de   memória  do  host  (RDMA).   35  
  36. 36. Orientação  à  Objetos   •  Suporte  a  orientação  à  objetos   •  Herança   •  Polimorfismo   class  Veiculo{   public:      __host__  __device__      Veiculo(){}      __host__  __device__      Veiculo(int  id){          ID          =  id  +  11;        }        int  ID;   };   class  Carro  :  public  Veiculo{   public:        __host__  __device__      Carro(){};        __host__  __device__      Carro(int  id){            vMax  =  28;          }                float  vMax;   };   36  
  37. 37. Orientação  à  Objetos   __global__     void  meuKernel(  Veiculo  *vet  ){          int  indice  =  blockDim.x  *  blockIdx.x  +  threadIdx.x;                if  (threadIdx.x  ==  0)              vet[indice]  =  Carro(indice);        else              vet[indice]  =  Onibus(indice);   }   37  
  38. 38. Outras  Funcionalidades   •  Operações  Atômicas   •  Stream   •  Alocação  dinâmica  de  memória   •  Pilha  e  Recursão   •  Dire.vas  OpenACC   38  
  39. 39. Técnicas  avançadas  de  u.lização   de  GPU  e  CUDA   Jose  Ricardo  da  Silva  Junior  

×