Loading AI tools
Da Wikipédia, a enciclopédia livre
A Unidade de Processamento Gráfico de Propósito Geral ou GPGPU (General Purpose Graphics Processing Unit) utiliza a GPU (graphics processing unit) para além de renderização gráfica tais como: processamento de imagem, visão computacional, inteligência artificial, cálculo numérico dentre outras aplicações. Ou seja, é a utilização da GPU para realizar a computação em aplicações que antes eram tratada pela CPU (Unidade Central de Processamento).
A Unidade de Processamento Gráfico de Propósito Geral se tornou prático e popular depois dos anos de 2001, por causa do advento de duas programáveis shaders e ponto flutuante. A partir dali a comunidade de computação cientifica começou a fazer testes com o hardware, seu primeiro teste foi com uma multiplicação de matrizes de rotina, um dos primeiros códigos científicos simples a correr mais rápido em GPUs era a implementação da fatoração LU.[1]
Para os primeiros esforços de se utilizar GPUs com processadores de uso geral, foi necessário reformular problemas computacionais em termos gráficos, foram apoiados por dois APIs(Interfaces de Programação de Aplicativos) principais OpenGL e DirectX. Os mais atuais fornecedores independentes de hardware incluem Microsoft DirectCompute e Apple/Grupo Khronos OpenCL.
DirectX é um conjunto de APIs responsável pela comunicação entre hardware e software durante a execução de vídeos e principalmente games.Algumas das suas versões são: DirectX 8 introdução Shader Model 1.1, DirectX 8.1 Pixel Shader Models 1.2, 1.3 e 1.4 e DirectX 9 definindo Shader Model 2.x e 3.0. Cada modelo de shader aumentou as flexibilidades e capacidades do modelo de programação, garantindo o hardware conforme segue o exemplo. A especificação DirectX 10 Shader Model 4.0 introduz que unifica a especificação de programação para vértice, geometria (Geometry "Shaders" é novo para DirectX 10) e processamento fragmento permitindo um melhor ajuste para hardware de shader unificada, proporcionando assim uma piscina computacional de recurso programável.
O OpenGL (Open Graphics Library) é uma API livre utilizada na computação gráfica, para desenvolvimento de aplicativos gráficos, ambientes 3D, jogos, entre outros.
O OpenGL é um conjunto de algumas centenas de funções, que fornecem acesso a praticamente todos os recursos do hardware de vídeo. Internamente, ele age como uma máquina de estados, que de maneira bem específica dizem ao OpenGL o que fazer. Usando as funções da API, você pode ligar ou desligar vários aspectos dessa máquina, tais como a cor atual, se transparência será usada, se cálculos de iluminação devem ser feitos, se haverá ou não o efeito de neblina, e assim por diante.
O núcleo do OpenGL é conhecido como “rendering pipeline” ou dutos de renderização. É importante notar que o OpenGL lida tanto com o desenhos na forma vetorial, definidos por vértices, como com mapas de bits, definidos pixel-a-pixel.
As GPU são processadores com múltiplos núcleos, que tem uma capacidade muito maior de processamentos de dados do que a CPU.[2]
Ela é encarregada do processamentos de múltiplos dados, para que isso aconteça, a GPU utiliza-se de um conjunto de stream(grande conjunto ordenado de dados) de maneira paralela. Para que isso seja eficiente o hardware dela é implementado seguindo um pipeline gráfico, ou seja, o pipeline foi implementado em varias unidades fazendo que a computação paralela seja a nível de dado. Outro aspecto importante é a sua velocidade de acesso a memoria que é muito mais rápidas que a CPU, pois a GPU se importa com o principio da localidade da memoria ao invés da computação genérica.[3]
GPUs só pode processar vértices e fragmentos independentes, mas pode processar muitos deles em paralelo. Isto é especialmente eficaz quando o programador quer processar muitas vértices ou fragmentos da mesma maneira. Neste sentido, as GPUs são processadores stream - processadores que podem operar em paralelo, executando um kernel em muitos registros em um fluxo de uma só vez.
A stream é simplesmente um conjunto de registros que requerem computação similar. Streams fornecer paralelismo de dados. Kernels são as funções que são aplicadas a cada elemento no córrego. Nos GPUs, vértices e fragmentos são os elementos em córregos e shaders de vértice e fragmento são os grãos a serem executados neles. Desde os elementos do processo GPUs independentemente não há nenhuma maneira de ter shaders ou dados estáticos. Para cada elemento só pode ler a partir da entrada, realizar operações sobre ele, e escrever para a saída. É possível ter várias entradas e várias saídas, mas nunca um pedaço de memória que é ser lidos e escritos.
Intensidade Aritmética é definida com o número de operações realizadas por palavra de memória transferida. É importante para aplicações GPGPU ter alta intensidade aritmética mais a latência de acesso à memória limitará aceleração computacional.[4]
Aplicações GPGPU ideais têm grandes conjuntos de dados, alto paralelismo e dependência mínima entre elementos de dados.
Há uma variedade de recursos computacionais disponíveis na GPU:
A forma mais comum para um fluxo de tomar em GPGPU é uma grade 2D porque este se encaixa naturalmente com o modelo de prestação construído em GPUs. Muitos cálculos mapear naturalmente em grades: álgebra matricial, processamento de imagem, a simulação de base física, e assim por diante.
Desde texturas são usados como memória, pesquisas de textura são utilizados como memória lê. Algumas operações podem ser feitas automaticamente pelo GPU por causa disso.
Kernels pode ser pensado como o corpo de loops. Por exemplo, um programador de operar em um grid sobre a CPU e pode ter um código que se parece com isso:
// Entrada e saida de grids tem 10000 x 10000 ou 100 milhões de elementos.
void transform_10k_by_10k_grid(float in[10000][10000], float out[10000][10000])
{
for (int x = 0; x < 10000; x++) {
for (int y = 0; y < 10000; y++) {
// A próxima linha vai executar 100 milhões de vezes
out[x][y] = do_some_hard_work(in[x][y]);
}
}
}
Nas linguagens atuais o controle de fluxo e feito por if-then-else, for e while. Tais estruturas de controle de fluxo foram recentemente adicionadas ao GPUs. Como as CPU tem comando muito longos é necessário que elas sejam bem estruturadas e controladas, já que a cada falha na previsão de uma ocorrência, ira ocorrer uma penalidade. De maneira parecida a GPU da NVIDIA GeForce 6 funciona. [6]
Atualmente as arquiteturas paralelas possuem alguns tipos de controle de fluxo, como instruções unicas ,dados múltiplos (SIMD) e instruções múltiplas e dados múltiplos(MIMD). Para que uma GPU possa implementar uma ramificação e necessário três SIMD ramificação, MIMD ramificação e códigos de condição.
Mas as ramificações tem um custo, ou seja, elas diminuem a performance das GPUs. Para que elas possam fazer as ramificações internas sem o suporte do hardware e necessário se utilizar de técnicas como Static Branch Resolution, Pre-computation, Z-Cull, Data-Dependent Looping With Occlusion Queries. [7]
A operação mapa simplesmente aplica a função dada (o kernel) para cada elemento na stream. Um exemplo simples é multiplicar cada valor na stream por uma constante (aumentando o brilho de uma imagem). A operação de mapa é simples de implementar na GPU. O programador gera um fragmento para cada pixel na tela e aplica-se um fragmento de programa para cada um. O resultado da stream que é do mesmo tamanho é armazenado no buffer de saida.
Alguns cálculos requerem o cálculo de uma stream menor (possivelmente uma stream de apenas um elemento) a partir de uma stream maior. Isto é chamado uma redução do fluxo. Geralmente uma redução pode ser realizada em vários passos. Os resultados da etapa anterior são usados como a entrada para a etapa atual e o intervalo no qual a operação é aplicada é reduzida até que apenas um elemento da stream continua.
Filtragem de fluxo é essencialmente uma redução não uniforme. Filtragem envolve a remoção de itens do fluxo com base em alguns critérios.
Consiste basicamente em um algoritmo que irra fazer uma varredura para detectar colisões, ou em outros casos na retirada de dados que não são importantes.[7]
No acesso a memoria de GPU existe duas operações de grande importância elas são a operação de escrita e leitura quando acessão de forma indireta a memoria, elas são denominadas como scatter e gather respectivamente.
A operação gather ira ler valores contidos em um lugar qualquer na memoria, para isso ela irá fazer acesso as texturas contidas na GPU.[3]
Já a operação de scatter irá escrever um valor em qualquer posição da memoria. Sendo assim ela é mais complicada, ou seja, ela não pode ser utilizada em um programa de fragmentos, porque em cada fragmento tem implícito o endereço de onde ele veio, e para onde ele deve retornar através do mapeamento em framebuffer. Para que isso não ocorra é utilizado o programa de vértices, em que uma operação de scatter é feita por vértice.
A operação de classificação transforma um conjunto não ordenado de elementos em um conjunto ordenado de elementos. A aplicação mais comum em GPUs está sendo usado redes de classificação.[7]
A classificação de rede vai ter um numero fixo de etapas nas quais os dados não vão ter relação, elas também terão um padrão de comunicação que será o de gather ao em vez scatter.
A operação de busca permite que o programador para encontrar um determinado elemento dentro do fluxo, ou, eventualmente, encontrar vizinhos de um elemento especificado, nesse caso e utilizado bastante em pesquisa a banco de dados. A GPU não é usada para acelerar a busca por um elemento individual, mas em vez disso é usada para executar várias pesquisas em paralelo. Dois exemplos de pesquisa são:
Uma variedade de estruturas de dados podem ser representados na GPU:
Na programação GPU existem diversas linguagens, mas somente duas tem maior ênfase, são elas CUDA e OpenCL. Ambas fornecem paralelismo de dados, e também uma linguagem de baixo nível para fazer a comunicação com o hardware. Apesar da CUDA ter maior desempenho, a OpenCL vem sendo olhada com maior interesse por se tratar de uma linguagem de programação aberta.[9]
OpenCL (Open Computing Language) é uma plataforma para escrever programas que funcionam em plataformas heterogêneas, consistindo em CPUs, GPUs, processadores de sinal digital ( DSPs ), field-programmable gate arrays (FPGAs) e outros processadores. OpenCL inclui uma linguagem (baseada em C99) para escrever kernels (funções executadas em dispositivos OpenCL), além de APIs que são usadas para definir e depois controlar as plataformas heterogênea. OpenCL permite programação paralela usando, tanto o paralelismo de tarefas, como de dados. Ela é um padrão aberto mantido pela organização sem fins lucrativos tecnologia consórcio Khronos Group.
A proposta OpenCL é similar às propostas OpenGL e OpenAL, que são padrões abertos da indústria para gráficos 3D e áudio, respectivamente. Ela possui alguns versões a mais recente é OpenCl 2.0.
Algumas empresas que implementam são IBM Corporation, NVIDIA, Intel, Aplle Inc dentre outras.
CUDA (Compute Unified Device Architecture) é uma plataforma de computação paralela de propósito geral que tira proveito das unidades de processamento gráfico (GPUs) NVIDIA para resolver muitos problemas computacionais complexos em uma fração do tempo necessário em uma CPU. Ela inclui a arquitetura de conjunto de instruções CUDA ISA (Instruction Set Architecture) e o mecanismo de computação paralela na GPU.
Para programar segundo a arquitetura CUDA™, os desenvolvedores hoje em dia podem usar C - uma das mais amplamente utilizadas linguagens de programação capaz de operações de baixo nível, que pode ser então executada com alta performance em um processador compatível com CUDA™.
Atualmente cientistas e desenvolvedores estão aplicando a GPU CUDA em controle de tráfego aéreo e em simulações da corrente sanguínea, para encontrar placas ocultas em artérias.[10]