Programação Paralela em OpenCL
description
Transcript of Programação Paralela em OpenCL
![Page 2: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/2.jpg)
Introdução
• Open Computing Language (OpenCL)– Padrão aberto, livre de royalties, para
programação paralela em ambientes heterogêneos
– Ambientes heterogêneos• CPUs multicore, GPUs many-core
– Framework• Arquitetura• Linguagem• API
![Page 3: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/3.jpg)
Introdução
• Neste tutorial...– Conceitos da arquitetura OpenCL– Breve visão da linguagem OpenCL C– APIs fundamentais para o desenvolvimento– Exemplo completo de aplicação– Integração com OpenGL
![Page 4: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/4.jpg)
Hello World
• Código sequencial
void ArrayDiff(const int* a, const int* b, int* c, int n){ for (int i = 0; i < n; ++i) { c[i] = a[i] - b[i]; }}
![Page 5: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/5.jpg)
Hello World
• Código OpenCL (kernel)
__kernel void ArrayDiff(__global const int* a, __global const int* b, __global int* c){ int id = get_global_id(0); c[id] = a[id] - b[id];}
![Page 6: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/6.jpg)
Aplicações OpenCL
Camadas de uma aplicação OpenCL
![Page 7: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/7.jpg)
Arquitetura OpenCL
• Arquitetura abstrata de baixo nível• Implementações mapeiam para entidades
físicas• Quatro modelos– Plataforma– Execução– Programação– Memória
![Page 8: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/8.jpg)
Arquitetura OpenCL
• Modelo de plataforma– Descreve entidades do ambiente OpenCL
![Page 9: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/9.jpg)
Arquitetura OpenCLHospedeiro
Dispositivo
Dispositivo
. . .Unidade de Computação Unidade de Computação
...
Elemento deProcessamento
Elemento deProcessamento
...
Elemento deProcessamento
Elemento deProcessamento
...
Modelo de Plataforma
![Page 10: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/10.jpg)
Arquitetura OpenCL
• Exemplo: GPU NVIDIA– GPU: dispositivo– Streaming Multiprocessor: unidade de
computação– Processor/Core: elemento de processamento
![Page 11: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/11.jpg)
Arquitetura OpenCL
• Modelo de execução– Descreve instanciação e identificação de kernels
![Page 12: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/12.jpg)
Arquitetura OpenCL
• Modelo de execução– Espaços de índices
1D 2D 3D
![Page 13: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/13.jpg)
Arquitetura OpenCL
Modelo de execução: itens e grupos de trabalho
Grupo de trabalho(work-group)
Item de trabalho(work-item)
![Page 14: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/14.jpg)
Arquitetura OpenCL
__kernel void f(...){ ...
Item de trabalho
Kernel
Instância
![Page 15: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/15.jpg)
Arquitetura OpenCL
Modelo de execução: identificadores
0 1
0
1
Grupo de trabalho:
(1, 0)
![Page 16: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/16.jpg)
Arquitetura OpenCL
Modelo de execução: identificadores
1
2
0
0
1
3
2 3
Item de trabalho:
(1, 2)
Identificador global
![Page 17: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/17.jpg)
Arquitetura OpenCL
Modelo de execução: identificadores
Item de trabalho:
(1, 0)
Identificador local
1
0
0
1
![Page 18: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/18.jpg)
Arquitetura OpenCLContexto
Dispositivos
Objetos de programa Objetos de memória
Filas decomandos
Kernels
mem
Modelo de execução: objetos
![Page 19: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/19.jpg)
Arquitetura OpenCL
• Modelo de execução: objetos– Toda comunicação com um dispositivo é feita
através da sua fila de comandos– Objetos de memória• Buffers: acesso direto via ponteiros• Images: acesso especial via samplers
![Page 20: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/20.jpg)
Arquitetura OpenCL
• Modelo de programação– Paralelismo de dados (data parallel): múltiplos
itens de trabalho para um kernel– Paralelismo de tarefas (task parallel): um item de
trabalho para um kernel
![Page 21: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/21.jpg)
Arquitetura OpenCL
• Modelo de memória– Descreve uma hierarquia de memória e o
compartilhamento de cada nível entre itens e grupos de trabalho
![Page 22: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/22.jpg)
Arquitetura OpenCL
Modelo de memória
Memória privada
- Exclusiva de cada item de trabalho- Leitura e Escrita
![Page 23: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/23.jpg)
Arquitetura OpenCL
Modelo de memória
Memória local
- Compartilhada pelo grupo de trabalho- Leitura e Escrita
![Page 24: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/24.jpg)
Arquitetura OpenCL
Modelo de memória
Memória global
- Compartilhada por todos os itens de trabalho- Leitura e Escrita
![Page 25: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/25.jpg)
Arquitetura OpenCL
Modelo de memória
Memória constante
- Compartilhada por todos os itens de trabalho- Somente leitura
![Page 26: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/26.jpg)
Arquitetura OpenCL
• Modelo de memória: consistência– Um item de trabalho lê corretamente o que outros
escrevem?
![Page 27: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/27.jpg)
Arquitetura OpenCL
Modelo de memória: consistência
- Memória é consistente para um item de trabalho
Item de trabalho
Memória
x
x
![Page 28: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/28.jpg)
Arquitetura OpenCL
Modelo de memória: consistência
- Memória é consistente para um grupo de trabalho após uma barreira (barrier)
Itens de trabalho
Memória
x
y
?
?
![Page 29: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/29.jpg)
Arquitetura OpenCL
Modelo de memória: consistência
- Memória é consistente para um grupo de trabalho após uma barreira (barrier)
Itens de trabalho
Memória
x
y
![Page 30: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/30.jpg)
Arquitetura OpenCL
Modelo de memória: consistência
- Memória é consistente para um grupo de trabalho após uma barreira (barrier)
Itens de trabalho
Memória
barrier()
![Page 31: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/31.jpg)
Arquitetura OpenCL
Modelo de memória: consistência
- Memória é consistente para um grupo de trabalho após uma barreira (barrier)
Itens de trabalho
Memória
y
x
![Page 32: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/32.jpg)
Arquitetura OpenCL
• Sincronização– Barreira: execução só prossegue após todos os
itens de trabalho de um mesmo grupo de trabalho a terem atingido
– Não há sincronização entre grupos de trabalho
![Page 33: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/33.jpg)
Linguagem OpenCL C
• Utilizada para a escrita de kernels• Baseada no padrão C99• Acrescenta extensões e restrições
![Page 34: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/34.jpg)
Linguagem OpenCL C
• Extensão: tipos vetoriais– Notação: tipo[# de componentes]– 1, 2, 4, 8 ou 16 componentes– Exemplos:
float4int8short2uchar16
![Page 35: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/35.jpg)
Linguagem OpenCL C
• Operações com tipos vetoriais– Entre vetores de mesmo número de componentes– Entre vetores e escalares
float4 v = (float4)(1.0, 2.0, 3.0, 4.0);float4 u = (float4)(1.0, 1.0, 1.0, 1.0);float4 v2 = v * 2;float4 t = v + u;
![Page 36: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/36.jpg)
Linguagem OpenCL C
• Definição de kernels– Qualificador __kernel– Todo kernel deve ser void
__kernel void f(…){ ...}
![Page 37: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/37.jpg)
Linguagem OpenCL C
• Qualificadores de espaço de endereçamento– Definem nível da memória apontada por um
ponteiro– __global, __local, __private e __const– Default: __private
![Page 38: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/38.jpg)
Linguagem OpenCL C
• Restrições– Ponteiros para função não são suportados– Funções e macros com número variável de
argumentos não são suportados– Qualificadores extern, static e auto não são
suportados– Não há suporte a recursão
![Page 39: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/39.jpg)
API de suporte: kernels
• Funções de identificação– Informações sobre espaço de índices, item e grupo de trabalho
get_global_id(uint dimindx)get_local_id(uint dimindx)get_group_id(uint dimindx)get_global_size(uint dimindx)get_local_size(uint dimindx)get_num_groups()get_work_dim()
![Page 40: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/40.jpg)
API de suporte: kernels
• Funções de sincronização
barrier(cl_mem_fence_flags flags)
Flags:
CLK_LOCAL_MEM_FENCECLK_GLOBAL_MEM_FENCE
![Page 41: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/41.jpg)
API de suporte: hospedeiro
• Ilustração através de um exemplo prático• Aplicação completa– Kernel para subtração dos elementos de dois
arrays
![Page 42: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/42.jpg)
Exemplo prático
• Exemplo de código executado no hospedeiro– Ilustra as principais etapas para o
desenvolvimento de soluções OpenCL– Multi-plataforma
![Page 43: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/43.jpg)
Exemplo prático
#ifdef __APPLE__#include <OpenCL/opencl.h>#else#include <CL/opencl.h>#endif
![Page 44: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/44.jpg)
Exemplo prático
cl_platform_id platformId;cl_device_id deviceId;
clGetPlatformIDs(1, &platformId, NULL);
clGetDeviceIDs( platformId, CL_DEVICE_TYPE_GPU, 1, &deviceId, NULL);
![Page 45: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/45.jpg)
Exemplo prático
cl_context context = clCreateContext( NULL, 1, &deviceId, NULL, NULL, NULL);
cl_command_queue queue = clCreateCommandQueue( context, deviceId, NULL, NULL);
![Page 46: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/46.jpg)
Exemplo prático
const char* source = "__kernel void ArrayDiff( \ __global const int* a, \ __global const int* b, \ __global int* c) \ { \ int id = get_global_id(0);\ c[id] = a[id] - b[id]; \ }";
![Page 47: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/47.jpg)
Exemplo prático
cl_program program = clCreateProgramWithSource( context, 1, &source, NULL, NULL);
![Page 48: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/48.jpg)
Exemplo prático
clBuildProgram( program, 0, NULL, NULL, NULL, NULL);
cl_kernel kernel = clCreateKernel( program,"ArrayDiff", NULL);
![Page 49: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/49.jpg)
Exemplo prático
#define N ...
cl_mem bufA = clCreateBuffer( context, CL_MEM_READ_ONLY, N * sizeof(int), NULL, NULL);
cl_mem bufB = ...;cl_mem bufC = ...;
CL_MEM_READ_WRITE
![Page 50: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/50.jpg)
Exemplo prático
int* hostA;
clEnqueueWriteBuffer( queue, bufA, CL_TRUE, 0, N * sizeof(int), hostA, 0, NULL, NULL);
![Page 51: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/51.jpg)
Exemplo prático
int* hostB;
clEnqueueWriteBuffer( queue, bufB, CL_TRUE, 0, N * sizeof(int), hostB, 0, NULL, NULL);
![Page 52: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/52.jpg)
Exemplo prático
clSetKernelArg( kernel, 0, sizeof(cl_mem), &bufA);clSetKernelArg( kernel, 1, sizeof(cl_mem), &bufB);clSetKernelArg( kernel, 2, sizeof(cl_mem), &bufC);
![Page 53: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/53.jpg)
Exemplo prático
const size_t globalSize[] = { N };
clEnqueueNDRangeKernel( queue, kernel, 1, NULL, globalSize, NULL, 0, NULL, NULL);
clFinish(queue);
![Page 54: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/54.jpg)
Exemplo prático
int* hostC;
clEnqueueReadBuffer( queue, bufC, CL_TRUE, 0, N * sizeof(int), hostC, 0, NULL, NULL);
![Page 55: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/55.jpg)
Exemplo prático
clReleaseMemObject(bufC);clReleaseMemObject(bufB);clReleaseMemObject(bufA);clReleaseKernel(kernel);clReleaseProgram(program);clReleaseCommandQueue(queue);clReleaseContext(context);
![Page 56: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/56.jpg)
Interoperação com OpenGL
• Em GPUs, é possível compartilhar estruturas entre OpenCL e OpenGL
• Exemplo prático: malha tridimensional– Vértices posicionados via OpenCL– Exibição via OpenGL– Compartilhamento de Vertex Buffer Object (VBO)• OpenCL: array de float4
![Page 57: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/57.jpg)
Interoperação com OpenGL
• Demonstração
![Page 58: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/58.jpg)
Interoperação com OpenGL__kernel void sine_wave( __global float4* pos, unsigned int width, unsigned int height, float time) { unsigned int x = get_global_id(0); unsigned int y = get_global_id(1);
Kernel
![Page 59: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/59.jpg)
Interoperação com OpenGL
float u = x / (float) width; float v = y / (float) height; u = u*2.0f - 1.0f; v = v*2.0f - 1.0f;
float freq = 4.0f; float w = sin(u * freq + time) * cos(v * freq + time) * 0.5f;
pos[y * width + x] = (float4)(u, w, v, 1.0f);}
![Page 60: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/60.jpg)
cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) platformId, 0};
context = clCreateContext( props, 1, &deviceId, NULL, NULL, NULL);
Criação do contexto
![Page 61: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/61.jpg)
Interoperação com OpenGL
#define BUFFER_SIZE ...
GLuint vbo;
glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData( GL_ARRAY_BUFFER, BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
Criação do VBO
![Page 62: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/62.jpg)
Interoperação com OpenGL
cl_mem vbo_cl;
vbo_cl = clCreateFromGLBuffer( context, CL_MEM_WRITE_ONLY, vbo, NULL); Criação do objeto de
memória a partir do VBO
![Page 63: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/63.jpg)
Interoperação com OpenGL
clEnqueueAcquireGLObjects( queue, 1, &vbo_cl, NULL, NULL, NULL);
Aquisição do VBO
![Page 64: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/64.jpg)
Interoperação com OpenGL
size_t globalSize[] = { MESH_WIDTH, MESH_HEIGHT };
clEnqueueNDRangeKernel( queue, kernel, 2, NULL, globalSize, NULL, 0, 0, 0);
clFinish(queue);Execução do
kernel
![Page 65: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/65.jpg)
Interoperação com OpenGL
clEnqueueReleaseGLObjects( queue, 1, &vbo_cl, NULL, NULL, NULL);
Liberação do VBO
![Page 66: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/66.jpg)
Considerações finais
• SDKs– NVIDIA CUDA SDK– ATI Streaming SDK– Intel OpenCL SDK (alpha)
• Aplicações em jogos: IA, física, simulações diversas
![Page 67: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/67.jpg)
Considerações finais
• Material disponível em
http://labs.v3d.com.br/
![Page 68: Programação Paralela em OpenCL](https://reader037.fdocuments.net/reader037/viewer/2022102801/56815445550346895dc25203/html5/thumbnails/68.jpg)
Dúvidas?