CUDA/Open CL

428 visualizações

Publicada em

Conceitos básicos de CUDA e OpenCL: das arquiteturas de computadores às diretivas de programação.

Publicada em: Ciências
  • Seja o primeiro a comentar

CUDA/Open CL

  1. 1. CUDA/OpenCL Arquiteturas Avancadas de Computadores Krissia de Zawadzki Instituto de F´ısica de S˜ao Carlos - Universidade de S˜ao Paulo 06 de Maio 2014 Krissia de Zawadzki CUDA/OpenCL 1 / 61
  2. 2. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Outline 1 CUDA - Introduc~ao 2 GPU e CUDA 3 Programando em CUDA 4 OpenCL 5 Caos 6 Conclus~ao Krissia de Zawadzki CUDA/OpenCL 2 / 61
  3. 3. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA - Introdu¸c˜ao CUDA Compute Uni
  4. 4. ed Device Architecture 3 Plataforma de computac~ao paralela e modelo de programac~ao 3 Desenvolvido pela NVIDIA e implementada para GPU's NVIDIA 3 Conjunto de instruc~oes e memoria diretamente acessveis ao programador Krissia de Zawadzki CUDA/OpenCL 3 / 61
  5. 5. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Background hist´orico Background hist´orico 2002: Stanford University Steam processing Prototipo e arquitetura muito parecida com GPU Baseline programmable stream processor Krissia de Zawadzki CUDA/OpenCL 4 / 61
  6. 6. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Background hist´orico Background hist´orico 2002: GeForce 3 e ATI Radeon 9700 3 Shaders programaveis Krissia de Zawadzki CUDA/OpenCL 5 / 61
  7. 7. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Background hist´orico Background hist´orico 2006: GeForce 8 Arquitetura uni
  8. 8. cada → CUDA! Krissia de Zawadzki CUDA/OpenCL 6 / 61
  9. 9. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Background hist´orico Background hist´orico 2006: GeForce 8 3 Programabilidade realmente exvel 3 Revolucionou os conceitos de pipeline de pixel e vertices 3 Cadeia de processadores Krissia de Zawadzki CUDA/OpenCL 7 / 61
  10. 10. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU’s com suporte para CUDA GPU’s com suporte para CUDA GeForce 8 3 8, 9, 100, 200, 400, 500 e 600-series (m´ın 256MB memloc) 3 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0, 3.5 e 5.0 GeForce GTX-750 (5.0) NVS 3 Quadro 295, 420, 450 3 NVIDIA NVS 300, 315, 510 3 1.1, 1.2, 2.1 e 3.0 NVIDIA NVS 510 (3.0) Krissia de Zawadzki CUDA/OpenCL 8 / 61
  11. 11. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU’s com suporte para CUDA GPU’s com suporte para CUDA QUADRO 3 Quadro NVS, Quadro FX, Quadro K 3 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0 e 3.5 QUADRO K600 (3.5) Tesla 3 D780, C870, C1060, C2050/2070, C2075 3 K20, K40 3 1.0, 1.3, 2.0, 3.5 Tesla K20 (3.5) Krissia de Zawadzki CUDA/OpenCL 9 / 61
  12. 12. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Aplica¸c˜oes Al´em de processamento gr´afico Krissia de Zawadzki CUDA/OpenCL 10 / 61
  13. 13. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Aplica¸c˜oes Krissia de Zawadzki CUDA/OpenCL 11 / 61
  14. 14. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Aplica¸c˜oes Ganho de desempenho em aplica¸c˜oes cient´ıficas Krissia de Zawadzki CUDA/OpenCL 12 / 61
  15. 15. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU GPU vs. CPU CPU 3 C´odigos sequenciais 3 Baixa lat^encia 3 Controle complexo GPU 3 Paralelismo de dados 3 Alto throughtput 3 Aritm´etica com pouco controle Krissia de Zawadzki CUDA/OpenCL 13 / 61
  16. 16. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU GPU vs. CPU CPU 3 Fluxo iterativo 7 Tempo de computa¸c˜ao 7 GPU 3 Opera¸c˜oes simult^aneas 7 Desvio de fluxo 7 Krissia de Zawadzki CUDA/OpenCL 13 / 61
  17. 17. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU CPU vs. GPU Krissia de Zawadzki CUDA/OpenCL 14 / 61
  18. 18. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU CPU vs. GPU Krissia de Zawadzki CUDA/OpenCL 14 / 61
  19. 19. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Linguagens e modelos de programa¸c˜ao paralela Linguagens e modelos de programa¸c˜ao paralela OpenMP shared memory limite de centenas de n´os CUDA alta escalabilidade portabilidade ´e mais simples! MPI capacidade de n´os 100.000 esfor¸co para portar o c´odigo OpenCL modelo de programa¸c˜ao padronizado suporte para AMD/ATI, NVIDIA, Apple e Intel Krissia de Zawadzki CUDA/OpenCL 15 / 61
  20. 20. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Arquitetura da GPU GPU - Unified processor array (GeForce 8800 GTX) Krissia de Zawadzki CUDA/OpenCL 16 / 61
  21. 21. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Estrutura de um programa CUDA Estrutura de um programa CUDA Trechos seriais ou com fraco paralelismo no codigo C do host Porc~ao altamente paralela no codigo C do kernel associado ao device Krissia de Zawadzki CUDA/OpenCL 17 / 61
  22. 22. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Estrutura de um programa CUDA CUDA Threads paralelas // de dados: Todas as threads rodam o mesmo codigo threadIdx: identi
  23. 23. cador da thread → de memoria e controle Krissia de Zawadzki CUDA/OpenCL 18 / 61
  24. 24. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Estrutura de um programa CUDA CUDA Thread Blocks Thread Blocks: Array (dim 2x2) the threads que cooperam entre si bloco: memoria compartilhada, operac~oes at^omicas e barreiras de sincronizac~ao blockIdx: identi
  25. 25. cador do bloco em um grid Krissia de Zawadzki CUDA/OpenCL 19 / 61
  26. 26. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Estrutura de um programa CUDA CUDA Id’s Ids s˜ao ´uteis para identificar os dados sob os quais cada thread ir´a trabalhar Conveniente para simplificar o de mem´oria em dados multidimensionais blockIdx: 1D (blockIdx.x) 2D (blockIdx.x, blockIdx.y) threadIdx: 1D (threadIdx.x), 2D (threadIdx.x, threadIdx.y), 3D (threadIdx.x, threadIdx.y, threadIdx.z) Krissia de Zawadzki CUDA/OpenCL 20 / 61
  27. 27. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Estrutura de um programa CUDA Par^ametros de configura¸c˜ao block: dimBlock ( Widthx , Widthy , , Widthz ) grid: dimGrid (Wgridx , Wgridy , Wgridz ) Kernel launching // Setup the execution configuration dim3 dimBlock (Width , Width , 1); dim3 dimGrid (1, 1, 1); // Launch the device computation threads ! MyKernelFunction dimGrid , dimBlock ( args ); Krissia de Zawadzki CUDA/OpenCL 21 / 61
  28. 28. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Modelo de Mem´oria CUDA Modelo de Mem´oria CUDA Memoria Global: comunica¸c˜ao host-device R/W conte´udo vis´ıvel por todas as threads tipicamente implementada como DRAM acesso de longa lat^encia (400-800 ciclos) 7 congestionamento throughput limitado (a 177 GB/s na GTX8800) Krissia de Zawadzki CUDA/OpenCL 22 / 61
  29. 29. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Modelo de Mem´oria CUDA Modelo de Mem´oria CUDA Memoria Constante: read only baixa lat^encia e alta largura de banda quando todas as threadas acessam o mesmo local Krissia de Zawadzki CUDA/OpenCL 22 / 61
  30. 30. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Modelo de Mem´oria CUDA Modelo de Mem´oria CUDA Memoria Compartilhada: 3 rapida altamente paralela apenas um bloco tem acesso Krissia de Zawadzki CUDA/OpenCL 22 / 61
  31. 31. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Modelo de Mem´oria CUDA Modelo de Mem´oria CUDA Registradores 3 o componente da memoria da GPU mais rapido acess´ıvel por uma threada Krissia de Zawadzki CUDA/OpenCL 22 / 61
  32. 32. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Vari´aveis CUDA Vari´aveis CUDA kernel: a vari´avel deve ser declarada no escopo da fun¸c˜ao kernel → fica dispon´ıvel somente no kernel application: a vari´avel deve ser declarada fora de qualquer fun¸c˜ao constant: a vari´avel deve ser declarada fora de qualquer fun¸c˜ao → limitado (a 64KB na GTX8800) Krissia de Zawadzki CUDA/OpenCL 23 / 61
  33. 33. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA Kernel Functions CUDA Kernel Functions Kernel functions: implementam o trecho paralelo de codigo a ser executado no device Sua chamada pode ser feita com as con
  34. 34. gurac~oes de blocos e de threads Krissia de Zawadzki CUDA/OpenCL 24 / 61
  35. 35. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA Kernel Functions Atribui¸c˜ao de threads base block-by-block 7 Runtime system coordena os blocos e as threads a serem executadas: mantem a lista de blocos e associa novos blocos a SM's livres recursos do SM unidades aritmeticas numero de threads que podem ser rastreadas e escalonadas simultaneamente Krissia de Zawadzki CUDA/OpenCL 25 / 61
  36. 36. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA Kernel Functions CUDA Warps Warps : conjunto de threads com ndices consecutivos A capacidade do warp (num. de threads) e dependente da implementac~ao Warp e a unidade para escalonar threads no SM SIMD ordem qualquer entre warps 7 diverg^encia causada por branchs Krissia de Zawadzki CUDA/OpenCL 26 / 61
  37. 37. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA Kernel Functions Compilador NVCC Baseado no Open64 (opensource originario do MIPSPro - SGI). Implementado em C e C++. NVidia atualmente investindo no LLVM. Existe um utilit´ario que converte LLVM IR (gerado por qualquer frontend de compilador LLVM) em PTX, que pode ser programado nas GPUs NVidia. Krissia de Zawadzki CUDA/OpenCL 27 / 61
  38. 38. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao CUDA Kernel Functions Defici^encias Equipe preferiu implementar codigo para o desa
  39. 39. o ECC2K-130 diretamente em codigo de maquina. BERNSTEIN, D. J. et al. Usable Assembly Language for GPUs: A Success Story. In: Workshop Records of Special-Purpose Hardware for Attacking Cryptographic Systems – SHARCS 2012. [s.n.], 2012. p. 169–178. Compilador NVCC muito lento para lidar com kernels contendo muitas instruc~oes. Registradores alocados de forma pouco e
  40. 40. ciente { muitas variaveis acabaram tendo de ser alocadas pelo NVCC na memoria compartilhada. Varios truques necessarios para obter uma implementac~ao em C aceitavel. Implementac~ao em Assembly 148% mais rapida que melhor implementac~ao em C. Krissia de Zawadzki CUDA/OpenCL 28 / 61
  41. 41. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Multiplica¸c˜ao Matricial: o Hello World do CUDA 푃 = 푀 * 푁 Σ︁ 푃푖푗 = 푘 푀푖,푘푁푘,푗 3 Paralelismo de dados! Cada elemento 푃푖푗 de 푃 pode ser calculado simultaneamente aos demais! Krissia de Zawadzki CUDA/OpenCL 29 / 61
  42. 42. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Representa¸c˜ao matricial em C Alocac~ao de memoria no C para arrays bidimensionais: Krissia de Zawadzki CUDA/OpenCL 30 / 61
  43. 43. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo C´odigo main C sequencial (host) int main ( void ){ // 1. Alocamos e inicializamos as matrizes M, N e P // Funcoes I/O leem as matrizes M e N ... // 2. Multiplicacao M * N MatMul (M,N,P, Width ); ... // 3. Funcao I/O para escrever a saida P // Liberamos a memoria de M, N e P return 0; } Krissia de Zawadzki CUDA/OpenCL 31 / 61
  44. 44. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Fun¸c˜ao C sequencial (host) void MatMul ( float *M; float *N, float *P, int Width ) { for ( int i = 0; i Width ; ++i) for (int j = 0; j Width ; ++j){ float sum = 0; for ( int k = 0; k Width ; ++k){ float m = M[i* Width + k]; float n = N[k* width + j]; sum += m * n; } P[i * Width + j] = sum ; } } Krissia de Zawadzki CUDA/OpenCL 32 / 61
  45. 45. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Portando o c´odigo para CUDA - aloca¸c˜ao de mem´oria cudaMalloc() aloca um objeto na Memoria Global par^ametros: endereco de um ponteiro para o objeto alocado, tamanho do objeto cudaFree() libera um objeto na Memoria Global par^ametro: ponteiro para o objeto Krissia de Zawadzki CUDA/OpenCL 33 / 61
  46. 46. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Portando o c´odigo para CUDA - aloca¸c˜ao Exemplo: int Width =64; float * Md , Nd; int size = Width * Width * sizeof ( float ); cudaMalloc (( void **) Md , size ); cudaMalloc (( void **) Nd , size ); ... cudaFree (Md ); cudaFree (Nd ); Krissia de Zawadzki CUDA/OpenCL 34 / 61
  47. 47. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Portando o c´odigo para CUDA - transfer^encia de dados cudaMemcpy() transfere dados entre o host e o device Assncrona par^ametros: ponteiro para o destino ponteiro para a fonte n´umero de bytes a serem copiados tipo de transfer^encia tipos: Host to Host Host to Device Device to Host Device to Device Krissia de Zawadzki CUDA/OpenCL 35 / 61
  48. 48. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Portando o c´odigo para CUDA - transfer^encia de dados Exemplo: ... int size = Width * Width * sizeof ( float ); ... cudaMemcpy (Md , M, size , cudaMemcyHostToDevice ); cudaMemcpy (Nd , N, size , cudaMemcyHostToDevice ); ... cudaMemcpy (Pd , P, size , cudaMemcyDeviceToHost ); Krissia de Zawadzki CUDA/OpenCL 36 / 61
  49. 49. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Portando o c´odigo para CUDA - fun¸c˜ao MatMul no device void MatMul ( float *M; float *N, float *P, int Width ){ int size = Width * Width * sizeof ( float ); float * Md , Nd , Pd; // 1. Alocamos memoria no device para M, N e P cudaMalloc (( void **)) Md , size ); cudaMemcpy (Md , M, size , cudaMemcyHostToDevice ); cudaMalloc (( void **)) Nd , size ); cudaMemcpy (Nd , N, size , cudaMemcyHostToDevice ); cudaMalloc (( void **)) Pd , size ); // 2. Evocamos a funcao kernel para a multiplicacao // 3. Copiamos o resultado P para a memoria do host cudaMemcpy (Pd , P, size , cudaMemcyDeviceToHost ); // Liberamos as memorias de M, N e P no device cudaFree (Md ); cudaFree (Nd ); cudaFree (Pd ); } Krissia de Zawadzki CUDA/OpenCL 37 / 61
  50. 50. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Fun¸c˜ao kernel MatMul Krissia de Zawadzki CUDA/OpenCL 38 / 61
  51. 51. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Kernel function - um pouco mais sobre especifica¸c˜oes global de
  52. 52. ne uma func~ao kernel device e host podem ser usadas simultaneamente 7 recurs~oes 7 variaveis estaticas 7 chamadas indiretas de func~oes por ponteiros Krissia de Zawadzki CUDA/OpenCL 39 / 61
  53. 53. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Configura¸c˜ao de execu¸c˜ao Exemplo: De
  54. 54. nir a multiplicac~ao matricial quando 푊푖푑푡ℎ = 32 em blocos Grids 2D com (2x2) blocos Blocos 2D com (16x16) threads Krissia de Zawadzki CUDA/OpenCL 40 / 61
  55. 55. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Configura¸c˜ao de execu¸c˜ao A configura¸c˜ao define a dimens˜ao do problema!!!! No exemplo anterior, usando blocos 1D podemos apenas trabalhar com 푊푖푑푡ℎ = 16 ! Solu¸c˜ao: Manipular dimGrid e dimBlock e dividir o c´alculo de peda¸cos da matriz resultado entre threads e blocos! Krissia de Zawadzki CUDA/OpenCL 41 / 61
  56. 56. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando blockIdx e threadIdx Solu¸c˜ao: tiles! Krissia de Zawadzki CUDA/OpenCL 42 / 61
  57. 57. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando blockIdx e threadIdx: nova fun¸c˜ao kernel __global__ void MatMulK ( float *Md , float *Nd , float *Pd , int Width ) { // linha e colunas do elemento de Pd int Row = blockIdx .y* TILE_WIDTH + threadIdx .y; int Col = blockIdx .x* TILE_WIDTH + threadIdx .x; float Pvalue = 0; // cada thread calcula um elemento da sub - matriz no bloco for ( int k = 0; k Width ; ++k) Pvalue += Md[ Row * Width +k] * Nd[k* Width +Col ]; Pd[ Row * Width + Col ] = Pvalue ; } Krissia de Zawadzki CUDA/OpenCL 43 / 61
  58. 58. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando blockIdx e threadIdx: par^ametros de configura¸c˜ao // configuracao para varios blocos dim3 dimBlock ( Width / TILE_WIDTH , Width / TILE_WIDTH ); dim3 dimGrid ( TILE_WIDTH , TILE_WIDTH ); // Lancamento do Kernel MatMulK dimGrid , dimBlock (Md , Nd , Pd , Width ); Krissia de Zawadzki CUDA/OpenCL 44 / 61
  59. 59. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Sincroniza¸c˜ao syncthreads() primitiva chamada por uma func~ao kernel o kernel que chamou
  60. 60. ca em espera ate que todas as threads terminem sua execuc~ao 7 conditionals if-then-else 7 threads em blocos diferentes n~ao podem sincronizar Krissia de Zawadzki CUDA/OpenCL 45 / 61
  61. 61. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Escalabilidade Transparente 3 Potencial para executar o mesmo codigo no hardware com um numero diferente de recursos de execuc~ao e escalabilidade transparente. Krissia de Zawadzki CUDA/OpenCL 46 / 61
  62. 62. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando a mem´oria para obter performance 3 reduzir o tra
  63. 63. co de dados da memoria global evita congestionamento 3 podemos aproveitar a localidade de dados para otimizar o acesso a dados na memoria da GPU 3 Threads que usam dados comuns podem colaborar! 3 Soluc~ao: tiling + shared memory Krissia de Zawadzki CUDA/OpenCL 47 / 61
  64. 64. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando a mem´oria para obter performance Krissia de Zawadzki CUDA/OpenCL 48 / 61
  65. 65. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando a mem´oria para obter performance 3 Threads 푃1,0 e 푃1,1 compartilham o elemento 푁1,0 3 Threads 푃0,0 e 푃1,0 compartilham o elemento 푁1,0 3 threads com elementos em comum devem estar associadas ao mesmo bloco e, assim, os dados comuns podem ser guardados na memoria compartilhada! Krissia de Zawadzki CUDA/OpenCL 49 / 61
  66. 66. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Usando a mem´oria para obter performance 3 reduc~ao de tra
  67. 67. co de dados na mem. global ∝ TILE WIDTH 3 P/ NxN blocos, a reduc~ao ∝ N 3 num. de fases e Width/ TILE WIDTH Krissia de Zawadzki CUDA/OpenCL 50 / 61
  68. 68. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Programando em CUDA: exemplo Kernel MatMul com mem´oria compartilhada __global__ voidMatMulK ( float *Md , float *Nd , float *Pd , int Width ) { __shared__ float Mds [ TILE_WIDTH ][ TILE_WIDTH ]; __shared__ float Nds [ TILE_WIDTH ][ TILE_WIDTH ]; int bx = blockIdx .x; int by = blockIdx .y; int tx = threadIdx .x; int ty = threadIdx .y; // Identificamos a linha e a coluna do elemento de Pd int Row = by * TILE_WIDTH + ty; int Col = bx * TILE_WIDTH + tx; float Pvalue = 0; // Loop sobre os tiles Nd e Md for ( int m = 0; m Width / TILE_WIDTH ; ++){ Mds [ty ][ tx] = Md[Row * Width + (m* TILE_WIDTH + tx )]; Nds [ty ][ tx] = Nd [(m+ TILE_WIDTH + ty )* Width + Col ]; _syncthreads (); for ( int k = 0; k TILE_WIDTH ; ++k) Pvalue += Mds [ty ][k] * Nds[k][ tx] _syncthreads (); } Pd[ Row * Width + Col ] = Pvalue ; } Krissia de Zawadzki CUDA/OpenCL 51 / 61
  69. 69. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao OpenCL OpenCL extens~ao de linguagem e API's p/ GPU's applicac~oes OpenCL s~ao portaveis para todos os processadores com suporte 3 sintaxe e primitivas semelhantes ao CUDA 7 performance ≈ CUDA Krissia de Zawadzki CUDA/OpenCL 52 / 61
  70. 70. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao OpenCL - arquitetura do device OpenCL - arquitetura do device Krissia de Zawadzki CUDA/OpenCL 53 / 61
  71. 71. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao OpenCL e CUDA OpenCL e CUDA OpenCL API call Explica¸c˜ao equivalente em CUDA get global id(0); ´ındice global do work item blockIdx.x ×blocDim.x + threadIdx.x get local id(0); ´ındice local do work group threadIdx.x get global size(0); tamanho do range ND gridDim.x ×blocDim.x get local size(0); tamanho de cada work group blockDim.x OpenCL conceito de paralelismo equivalente em CUDA Kernel Kernel programa Host programa Host ND range (espa¸co de ´ındice) Grid work item Thread work group Block __kernel void vadd ( __global const float *a, __global const float *b, __global float * result ){ int id = get_global_id (0) ; result [id] = a[id ]+b[id ]; } Krissia de Zawadzki CUDA/OpenCL 54 / 61
  72. 72. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Exemplo de c´odigo OpenCL: multiplica¸c˜ao matricial Exemplo de c´odigo OpenCL: multiplica¸c˜ao matricial # define BLOCK_SIZE 16 __kernel void matrixMul ( __global float * P, __global float * M, __global float * N, int Width ) { int bx = get_group_id (0) , by = get_group_id (1); int tx = get_local_id (0) , ty = get_local_id (1); int mBegin = Width * BLOCK_SIZE * by; int mEnd = aBegin + Width - 1; int mStep = BLOCK_SIZE ; int nBegin = BLOCK_SIZE * bx; int nStep = BLOCK_SIZE * Width ; for (int m = mBegin , n = nBegin ; m = mEnd ; m += mStep , n += nStep ) { __local float Ms[ BLOCK_SIZE ][ BLOCK_SIZE ]; __local float Ns[ BLOCK_SIZE ][ BLOCK_SIZE ]; Ms[ty ][ tx] = M[m + Width * ty + tx ]; Ns[ty ][ tx] = N[n + Width * ty + tx ]; barrier ( CLK_LOCAL_MEM_FENCE ); for (int k = 0; k BLOCK_SIZE ; ++k) Psub += Ms[ty ][k] * Ns[k][ tx ]; barrier ( CLK_LOCAL_MEM_FENCE ); } int p = Width * BLOCK_SIZE * by + BLOCK_SIZE * bx; P[p + Width * ty + tx] = Psub ; } Krissia de Zawadzki CUDA/OpenCL 55 / 61
  73. 73. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Equa¸c˜ao diferencial com caos ¨푥 + 푥3 = sin(Ω푡) (Ω1,Ω2,Ω3, · · · ,Ω푁−1) 푑푥 (푡1, 푡2, · · · , 푡푓 ) = 푢 푑푡 푥0 푢0 integrac~ao Runge-Kutta 4 · · · 푑푡1 푑푡 푡0 푡푓 Expoente de Lyapunov |훿Z(푡)| ≈ 푒휆푡|훿Z0| Krissia de Zawadzki CUDA/OpenCL 56 / 61
  74. 74. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos GPU CUDA version: v5050 CUDA Devices: 1 0: GeForce GTX 650: 3.0 Global memory: 2047mb Shared memory: 48kb Constant memory: 64kb Block registers: 65536 Multiprocessors: 2 Max threads per multiprocessor: 2048 Warp size: 32 Threads per block: 1024 Max block dimensions: [ 1024, 1024, 64 ] Max grid dimensions: [ 2147483647, 65535, 65535 ] Krissia de Zawadzki CUDA/OpenCL 57 / 61
  75. 75. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - resultados 푥 e 푢 como func~ao de 푡 Krissia de Zawadzki CUDA/OpenCL 58 / 61
  76. 76. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - resultados Espaco de fase 푢 por 푥 Krissia de Zawadzki CUDA/OpenCL 58 / 61
  77. 77. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - resultados Expoente de Lyapunov Krissia de Zawadzki CUDA/OpenCL 58 / 61
  78. 78. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - an´alise de desempenho Krissia de Zawadzki CUDA/OpenCL 59 / 61
  79. 79. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - an´alise de desempenho Krissia de Zawadzki CUDA/OpenCL 59 / 61
  80. 80. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Equa¸c˜ao diferencial com caos Caos - an´alise de desempenho Krissia de Zawadzki CUDA/OpenCL 59 / 61
  81. 81. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Conclus˜oes 3 Uso de GPU's e altamente recomendado em aplicac~oes com paralelismo de dados 3 Cada vez mais aplicac~oes exigir~ao alta performance e fomentar~ao o desenvolvimento de GPU's e de modelos de programac~ao paralelos 3 CUDA e um modelo de programac~ao inteligvel e permite explorar e
  82. 82. cientemente o paralelismo de aplicac~oes e os recursos da GPU 3 Parallel Thinking: antes de portar um codigo para rodar na GPU e importante reconhecer quais os trechos sequenciais e os paralelos e explorar ao maximo este usando os recursos GPU Krissia de Zawadzki CUDA/OpenCL 60 / 61
  83. 83. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Refer^encias 3 Kirk, D. ; Hwu, W.W. Programming massively parallel processors 3 www.nvidia.com/object/gpu-applications.html 3 https://developer.nvidia.com/cuda-gpus 3 http://cs.nyu.edu/courses/spring12/CSCI-GA.3033-012/ Krissia de Zawadzki CUDA/OpenCL 61 / 61
  84. 84. Krissia de Zawadzki CUDA/OpenCL 1 / 13
  85. 85. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Tesla: Alto paralelismo da arquitetura Cada GPU G200b (com arquitetura Tesla) contem 30 SMs (Streaming Multiprocessors). Uma placa de v´ıdeo pode ter mais de uma GPU. Por exemplo, a GTX295 possui duas dessas GPUs. Cada um desses SMs contem 8 ALUs (Arithmetic-Logic Units). NVidia chama ALUs de “CUDA cores”, mas esse nome ´e ilus´orio, pois n˜ao se tratam de cores completos (com unidade de execu¸c˜ao, etc.) Alto throughput { e possvel requisitar para cada ALU uma operac~ao logica ou aritmetica por ciclo. Krissia de Zawadzki CUDA/OpenCL 2 / 13
  86. 86. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Tesla: Limita¸c˜oes impostas pela arquitetura Entretanto, cada ALU e construda na forma de um pipeline de varios estagios, apresentando muitos ciclos de lat^encia (da ordem de 24 ciclos). As 8 ALUs de um SM precisam executar a mesma instruc~ao ao longo de 4 ciclos, que e o tempo de resposta do dispatcher de instruc~oes. Por isso, cada instru¸c˜ao precisa ser executada pelo menos um total de 32 vezes. Isso ´e chamado de um warp. Para superar ambas as limitac~oes, o programa deve ser organizado de forma a executar em cada SM um numero de threads bem maior que o numero de ALUs disponveis. O dispatcher da Tesla precisa de pelo menos 2 warps para funcionar de forma cont´ınua, ent˜ao o m´ınimo ´e de 64 threads para n˜ao desperdi¸car oportunidades de inserir opera¸c˜oes nas ALUs. Recomenda-se de 128 a 192 threads. Dessas threads, apenas 8 executam simultaneamente por vez. Ent˜ao, cada thread fica ociosa ciclos o suficiente para compensar a lat^encia de cada opera¸c˜ao. Krissia de Zawadzki CUDA/OpenCL 3 / 13
  87. 87. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Tesla: Instru¸c˜oes condicionais Instru¸c˜oes subsequentes a uma compara¸c˜ao podem verificar se os operandos eram iguais (eq), diferentes (ne), um menor que o outro (lt), etc. A instru¸c˜ao s´o executa se a condi¸c˜ao for verdadeira, caso contr´ario a ALU fica ociosa por um ciclo. Inspirado na arquitetura ARM. Por´em capaz de memorizar o resultado de at´e 4 compara¸c˜oes ($p0–$p3) em vez de somente a ´ultima realizada. No ARM, evita esvaziar o pipeline em pequenas condicionais dif´ıceis de prever. Na GPU, evita a diverg^encia de warps. Krissia de Zawadzki CUDA/OpenCL 4 / 13
  88. 88. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Tesla: Recursos compartilhados de uma SM Cada SM tem 16384 registradores de 32 bits que s~ao divididos igualmente entre as threads. O conjunto de instruc~oes e capaz de enderecar no maximo 128 registradores por thread. Porem o ultimo registrador ($r127) e somente-escrita, apelidado de bitbucket. Se alocarmos menos de 128 threads por SM, estaremos desperdi¸cando registradores! Cada SM tem 16384 bytes de memoria compartilhada. Essa memoria e dividida em 16 bancos de memoria. Apenas enderecos situados em bancos diferentes podem ser acessados simultamente no mesmo ciclo. Essa mem´oria ´e entrela¸cada. Cada 4 bytes (32 bits) adjacentes s˜ao colocados em um banco diferente. Se duas threads tentarem acessar simultameamente o mesmo banco, o acesso ´e serializado pelo hardware e perde-se paralelismo. Krissia de Zawadzki CUDA/OpenCL 5 / 13
  89. 89. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Tesla: Mem´oria global A memoria global e compartilhada entre todas as SMs e e acessvel tambem pela CPU hospedeira. A lat^encia de acesso e na faixa de 400 a 600 ciclos. O throughput e de no maximo um acesso de 32 bits para cada SM por ciclo. Na arquitetura Tesla, n~ao existe cache. O programador deve explicitamente copiar os dados para memorias mais locais, conforme necessario para obter desempenho. Krissia de Zawadzki CUDA/OpenCL 6 / 13
  90. 90. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades GPU Fermi: Principais diferen¸cas Cache para mem´oria global; mais mem´oria compartilhada; dobro de registradores. Qu´adruplo de ALUs em cada SM. NVidia aumentou o poder de uma SM em vez de aumentar muito o n´umero de SMs, reduzindo n´umero de transistores necess´arios para o mesmo pico de GFLOPS. Warps agora duram 2 ciclos e, devido `as 2 unidades de dispatch, agora ´e poss´ıvel executar 2 warps simultaneamente em uma SM, um em cada grupo de 16 ALUs. Portanto, o tamanho do warp continua sendo de 32 threads. Melhor suporte a precis˜ao dupla. Por´em apenas um warp por vez (metade do throughput da precis˜ao simples). Krissia de Zawadzki CUDA/OpenCL 7 / 13
  91. 91. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Unified memory - CUDA6 Unified memory - CUDA6 7 mem´orias da CPU e da GPU eram fisicamente distintas e separadas pelo PCI-Express bus 3 Unified memory permite `a CPU o acesso direto a dados da GPU e vice-versa 3 H´a uma managed memory que torna dads acess´ıveis para CPU e para GPU por um ´unico ponteiro Krissia de Zawadzki CUDA/OpenCL 8 / 13
  92. 92. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Top 500 - m´aquinas com CUDA Top 500 - m´aquinas com CUDA Krissia de Zawadzki CUDA/OpenCL 9 / 13
  93. 93. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Performance em aplica¸c˜oes cient´ıticas - Tesla K40 Performance em aplica¸c˜oes cient´ıticas - Tesla K40 Krissia de Zawadzki CUDA/OpenCL 10 / 13
  94. 94. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Papers Web of Science Papers Web of Science Krissia de Zawadzki CUDA/OpenCL 11 / 13
  95. 95. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Tend^encias de sal´ario IT Tend^encias de sal´ario IT Krissia de Zawadzki CUDA/OpenCL 12 / 13
  96. 96. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades Tend^encias de emprego IT Tend^encias de emprego IT Krissia de Zawadzki CUDA/OpenCL 13 / 13

×