OpenCL na negociação - página 3

 

AMD Developer Central: Série de webinars de programação OpenCL.2. Introdução ao OpenCL



2- Introdução ao OpenCL

Este vídeo fornece uma introdução detalhada ao OpenCL, uma plataforma para computação paralela que pode usar CPUs e GPUs para acelerar os cálculos. Os programas escritos em OpenCL podem ser executados em diferentes dispositivos e arquiteturas, permitindo a portabilidade do código em diferentes plataformas. O vídeo discute os diferentes modelos de execução no OpenCL, incluindo paralelismo de dados e paralelismo de tarefas, e também aborda os diferentes objetos e comandos usados no OpenCL, como objetos de memória, filas de comandos e objetos de kernel. O vídeo também aborda as vantagens e limitações do uso do OpenCL, como a necessidade de gerenciamento explícito de memória e o potencial para melhorias significativas de desempenho em programas paralelos.

  • 00:00:00 Nesta seção, o palestrante apresenta o OpenCL e sua capacidade de usar CPUs e GPUs para acelerar cálculos paralelos, resultando em aumentos de velocidade significativos. Embora números como 100X ou 1000X às vezes sejam citados, realisticamente, acelerações de cerca de 10-20X são esperadas para programas otimizados. OpenCL pode escrever código portátil em diferentes dispositivos e arquiteturas; portanto, os programas escritos para GPUs AMD normalmente também podem ser executados em GPUs NVIDIA. Com a implementação da AMD, tanto a implementação da CPU quanto da GPU do OpenCL são fornecidas, ao contrário de algumas das implementações de outros concorrentes. A seção termina com uma visão geral da computação heterogênea e como o OpenCL se encaixa nela.

  • 00:05:00 Nesta seção, o palestrante faz uma introdução ao OpenCL, que é uma plataforma de baixo nível e verbosa que pode ser recompensadora em termos de desempenho se o aplicativo tiver as características certas. OpenCL é um modelo baseado em plataforma que consiste em uma API de host, um modelo de dispositivos conectados e um modelo de memória. Os dispositivos são vistos como uma coleção de unidades de computação e cada unidade de computação é dividida em elementos de processamento que são executados no SIMD. O modelo de execução é baseado na noção de kernel, que é a unidade de código executável que pode ser executado em paralelo em vários dados. Além disso, o OpenCL fornece um conjunto de filas que permitem a execução assíncrona de operações de leitura e gravação e execução do kernel, que podem estar em ordem ou fora de ordem.

  • 00:10:00 Nesta seção, o palestrante discute os dois principais modelos de execução em OpenCL: paralelismo de dados e paralelismo de tarefas. O modelo de dados paralelos é o mais eficiente para execução em GPUs e envolve um domínio de computação N dimensional onde cada elemento individual é chamado de item de trabalho que pode potencialmente ser executado em paralelo. A execução de itens de trabalho pode ser agrupada em dimensões locais chamadas grupos de trabalho que são executados em uma das unidades de computação disponíveis. O palestrante também explica como o loop está implícito no mundo paralelo de dados do OpenCL e como a rotina de obtenção de identificador global é usada para indexar em a e b.

  • 00:15:00 Nesta seção, o palestrante aborda a memória local, que é semelhante a um cache e é gerenciada pelo usuário, sendo de baixa latência e mais rápida que a memória global. A função de sincronização permite que os itens de trabalho gravem em um local de memória, aguardem a conclusão e, em seguida, façam com que outro item de trabalho leia esse local de memória e obtenha o valor gravado pelo item de trabalho anterior. A sincronização só pode ser feita dentro do grupo de trabalho. O OpenCL também oferece suporte ao paralelismo de tarefas, executado por um único item de trabalho, e se beneficia do uso do modelo de enfileiramento OpenCL e dos recursos de sincronização da API do host, permitindo código compilado nativamente. O OpenCL difere do C porque a hierarquia de memória de GPUs específicas é explicitamente exposta e o programador pode induzir uma ordenação e consistência dos dados por meio do uso de operações de barreira e sincronização.

  • 00:20:00 Nesta seção, o palestrante discute as vantagens do OpenCL, como seus poderosos recursos de desempenho. No entanto, eles apontam que o gerenciamento de memória em OpenCL requer operações explícitas, que podem ser complicadas e requerem consideração cuidadosa do algoritmo. O modelo de compilação é baseado em OpenGL e possui um modelo de compilação online que permite a passagem de fluxos ou strings de código-fonte OpenCL para compilação online. O OpenCL é construído em torno do contexto, uma coleção de dispositivos e objetos de memória, e as filas são usadas para enviar o trabalho a um dispositivo específico associado ao contexto. Objetos de memória são buffers, que são blocos unidimensionais de memória que podem ser considerados arrays.

  • 00:25:00 Nesta seção, o palestrante explica os diferentes objetos OpenCL, incluindo objetos de memória, imagens, programas e kernels. Os objetos de memória podem ser buffers ou tipos de imagem, onde as imagens possuem uma implementação de hardware para otimizar o acesso. Os programas que definem kernels para execução podem ser construídos e extraídos, e os valores de argumento do kernel podem ser definidos usando objetos do kernel. Filas de comando são usadas para enfileirar kernels e outros comandos para execução. Além disso, os eventos OpenCL são úteis para criar dependências entre comandos e consultar o status dos comandos. O palestrante também dá exemplos de como consultar dispositivos e seus IDs.

  • 00:30:00 Nesta seção, o palestrante explica como OpenCL retorna códigos de erro e objetos. Se uma função retornar um objeto CL, ela retornará esse objeto como resultado. Mas se não estiver retornando um objeto CL, retornará o código de erro como resultado. O contexto é discutido e como a memória é alocada no nível do contexto, o que significa que os buffers e as imagens são compartilhados entre os dispositivos. O palestrante também menciona a função CL get X info, especificamente CL get device info, que permite aos desenvolvedores consultar os recursos do dispositivo para determinar qual dispositivo é mais adequado para o algoritmo. Por fim, o palestrante discute buffers e imagens e como os kernels podem acessá-los, juntamente com as restrições de acesso a imagens.

  • 00:35:00 Nesta seção, o palestrante discute como alocar buffers e imagens no OpenCL, incluindo como descrever como os buffers serão acessados e os benefícios do uso de imagens. O palestrante também explica como acessar dados de objeto de memória usando comandos explícitos e como colocar comandos em fila em uma fila. Além disso, o vídeo explica como mapear uma região e transferir dados entre buffers, bem como as vantagens e desvantagens de usar unidades DMA. A seção conclui discutindo objetos de programa e kernel e definindo valores de argumento.

  • 00:40:00 Nesta seção, o palestrante discute o despacho e as dependências no OpenCL. Eles explicam como o dispatch será executado com base no domínio ou grade de execução e como as dependências podem ser configuradas para garantir que as coisas não se sobreponham. O orador explica ainda os argumentos do comando NQ, que têm em conta o número de eventos em lista de espera e o evento associado ao comando. Por fim, o palestrante apresenta uma visão geral da linguagem OpenCL C, que é baseada em C e possui algumas restrições e acréscimos, como tipos de vetores e primitivas de sincronização. A linguagem permite itens de trabalho e grupos de trabalho, bem como qualificadores de espaço de endereço e funções integradas.

  • 00:45:00 Nesta seção, o palestrante dá uma breve visão geral do OpenCL e seus recursos, como os diferentes espaços de endereço, tipos de vetores e tipos escalares que podem ser usados em kernels de programação. Eles também discutem como criar objetos de memória e construir e executar programas usando a API OpenCL. O palestrante então aborda uma questão sobre como o paralelismo de dados em OpenCL difere do desdobramento de loop em compiladores.

  • 00:50:00 Nesta seção, o palestrante explica o conceito de execução paralela de dados e as dificuldades dos componentes em fazê-lo de forma eficiente. Ele também enfatiza a necessidade de explicitamente paralelizar programas para OpenCL ou qualquer outro modelo. O inq_marker é outro tópico que é abordado e como ele é útil em cues fora de ordem. O palestrante reitera que a memória constante significa que os valores são constantes e é usada em GPUs especiais para carregar em uma memória constante muito rápida, que é somente leitura. Ele sugere verificar a OpenCL Zone no site da MD para obter mais informações sobre OpenCL e programação paralela. Por fim, ele fala sobre como get_global_ID(0) retornaria o mesmo valor para cada chamada do kernel.

  • 00:55:00 Nesta seção, o palestrante explica que quando dois aplicativos diferentes estão executando e tentando usar o OpenCL na mesma máquina, todas as implementações de hoje compartilharão o hardware e o sistema operacional multiplexará os aplicativos. Eles recomendam o uso de criadores de perfil visuais para OpenCL, como o plug-in do Visual Studio ou a versão de linha de comando do Linux, que permite consultar informações sobre id Hardware. A sobrecarga de carregar dados no objeto de imagem ou buffer dependeria do dispositivo, onde transferi-los pelo barramento PCIe teria maior latência. Por fim, o palestrante mencionou que a nova série de GPUs AMD 680 cem e as melhores práticas de programação para elas são semelhantes à arquitetura Evergreen, na qual são baseadas.
 

AMD Developer Central: série de webinars de programação OpenCL. 3. Arquitetura da GPU



3 - Arquitetura da GPU

Este vídeo fornece uma visão geral da arquitetura da GPU, observando as origens e o uso principal das GPUs como processadores gráficos. As GPUs são projetadas para processar pixels com alto grau de paralelismo, em contraste com CPUs projetadas para processamento escalar com pipelines de baixa latência. A arquitetura das GPUs é otimizada para tarefas específicas de gráficos, que podem não ser adequadas para computação de uso geral. O palestrante explica como a GPU maximiza a taxa de transferência de um conjunto de threads em vez de minimizar a latência de execução de um único thread. A arquitetura do bloco do motor da GPU também é discutida, incluindo compartilhamentos de dados locais, frentes de onda e grupos de trabalho. O vídeo explora vários recursos de arquitetura de GPU que ajudam a aumentar a quantidade de empacotamento que o compilador pode fazer, incluindo a emissão de operações dependentes em um único pacote e o suporte a contadores dependentes com compartilhamento beta global. Embora os designs dos núcleos da GPU e da CPU possam ser semelhantes, suas cargas de trabalho precisarão convergir para que tenham designs semelhantes.

Neste vídeo sobre arquitetura de GPU, o palestrante aprofunda o conceito de barreiras e sua função. Quando um grupo de trabalho contém várias frentes de onda em uma GPU, barreiras são usadas para sincronizar essas frentes de onda. No entanto, se existir apenas uma frente de onda de trabalho em um grupo, as barreiras perderão o sentido e serão reduzidas a não-operações.

  • 00:00:00 Nesta seção, os apresentadores apresentam o objetivo do webinar, que é fornecer uma visão geral da arquitetura de GPU de uma perspectiva diferente em comparação com a abordagem tradicional de descrever a arquitetura de baixo nível ou otimizações. Os apresentadores pretendem contextualizar a arquitetura da GPU, discutindo suas origens e uso principal como processadores gráficos. Eles explicam como as GPUs são projetadas para processar pixels com alto grau de paralelismo, diferente das CPUs projetadas para processamento escalar com pipelines de baixa latência. Os apresentadores também abordam como a arquitetura das GPUs pode não ser adequada para computação de uso geral devido a seus blocos de hardware otimizados projetados para acelerar tarefas específicas de gráficos.

  • 00:05:00 Nesta seção, aprendemos como executar programas de fragmentos independentes e relacionados a um único pixel, escritos em GLSL ou HLSL, e como esse padrão de programação permite um paralelismo eficiente sem análise de dependência ou comunicação entre pixels. O hardware foi projetado para executar o código do sombreador em vários pixels de uma só vez, conhecido como frente de onda, mas com o problema de código de bloco e ramificações. O problema surge quando todas as ramificações seguem o mesmo caminho, causando um problema, mas o hardware gera uma máscara para garantir que todos os pixels estejam executando a mesma instrução.

  • 00:10:00 Nesta seção, o palestrante discute como a execução de Cindy requer instruções simples e o uso de instruções vetoriais. Embora as instruções vetoriais possam ser geradas por hardware ou um compilador, elas podem tornar o desenvolvimento complicado e difícil devido à necessidade de empacotamento manual de diferentes operações, mascaramento de ramificação e codificação manual cuidadosa. Por outro lado, programar a execução Cindy usando instruções vetoriais tem o risco de fazer o desenvolvedor pensar que as pistas se ramificam independentemente, o que não é verdade. Apesar disso, ainda é mais fácil para os programadores pensar e para as GPUs AMD atuais, o mascaramento é controlado pelo hardware. Isso é importante considerar para computação, que é o objetivo da palestra, pois pode afetar o desempenho, especialmente com divergência de ramificação na Waveland mais ampla.

  • 00:15:00 Nesta seção, o palestrante discute os aspectos visíveis das arquiteturas de GPU baseadas em throughput computing, o que significa que, se um vetor de instrução parar em uma GPU, o que pode acontecer se a adição de ponto flutuante levar alguns ciclos para concluída, a mesma instrução pode ser usada para cobrir o tempo de parada no próximo vetor, tornando a decodificação da instrução mais eficiente. O palestrante explica que, em vez de aumentar a largura do vetor, o que pode reduzir a utilização de ALUs, várias frentes de onda podem inserir instruções de outros threads em execução, dando a probabilidade de não travar simplesmente enquanto espera que as unidades de textura retornem os dados da memória. No entanto, uma única frente de onda leva mais tempo para ser executada dessa maneira devido ao funcionamento da arquitetura.

  • 00:20:00 Nesta seção, o vídeo explica como a GPU maximiza a taxa de transferência de um conjunto de threads em vez de minimizar a latência de execução de um único thread. Isso significa que a GPU tenta aumentar a utilização de threads esperando que a primeira thread conclua a execução e, em seguida, alimentando a próxima frente de onda, enquanto os resultados do primeiro conjunto de pixels são reutilizados para manter o pipeline o mais próximo possível da ocupação total. . A GPU mantém um grande conjunto de registradores para cobrir toda a largura do vetor para cada thread em execução, ocupando espaço no dispositivo, que é dimensionado com o número de estados e a largura do vetor. A GPU é projetada para cobrir a latência e, portanto, em vez de minimizar a latência, a GPU maximiza a largura de banda da memória disponível para que possa satisfazer todo o paralelismo, usando caches de textura e memória local para reutilização de dados entre itens de trabalho.

  • 00:25:00 Nesta seção, o palestrante discute como caches e regiões de memória compartilhada controladas por programa podem reduzir a transferência de dados, permitindo que os dados sejam copiados apenas uma vez da interface da memória principal e depois reutilizados por diferentes itens de trabalho em caminhos variados. Eles explicam como o cache de textura é projetado para impor automaticamente a estrutura 2D em seus dados de forma eficiente para capturar acessos 2D pelos quads. As regiões de dados locais oferecem um controle consideravelmente maior, mas é responsabilidade do desenvolvedor estruturar as cargas com eficiência para usar essa memória e compartilhar dados para reduzir os requisitos de memória global. A seção também explora como a GPU pode ser vista como uma coleção de núcleos Cindy conectados com vários estados de programa intercalando 4, 8 ou 16 threads para cobrir a latência do pipeline. O trade-off entre o número de núcleos e a densidade da ALU é discutido, com o benefício de aumentar a utilização, dependendo da carga de trabalho.

  • 00:30:00 Nesta seção, o palestrante discute as semelhanças e diferenças entre os designs de núcleo de CPU e GPU, usando exemplos como Andy Phenom 2 X6 6 e Intel i7. Enquanto a abordagem adotada pelo Pentium 4 e ultraSPARC T2 envolvia tamanhos de núcleo maiores com vários conjuntos de estado para aumentar o paralelismo do nível de instrução, as GPUs estão no extremo do espectro com um alto grau de balanceamento de dados. Os detalhes técnicos do AMD Radeon HD 5870 também são discutidos, destacando sua alta largura de banda e o número de formas de onda concorrentes disponíveis que dependem do número de registros usados por cada frente de onda. O palestrante conclui que, embora possa haver semelhanças no espaço de design entre CPU e GPU nove, suas cargas de trabalho precisarão convergir para que tenham designs semelhantes.

  • 00:35:00 Nesta seção, aprendemos sobre os elementos de design da GPU, incluindo compartilhamentos de dados locais e frentes de onda e grupos de trabalho nos quais ela está dividida. O design da GPU inclui um processador de comando de despacho do coronel que gera frentes de onda, que são atribuídas a uma unidade SIMD disponível que possui recursos suficientes para caber no espaço. O chip inteiro tem 20 motores Cindy com 8 bancos de memória GDDR5 para crossbars e caches. Além disso, apresenta um modelo relaxado de consistência de memória global, que requer instruções de cerca para garantir direitos de visibilidade, permitindo que os motores Cindy e as unidades fixas mantenham o mais alto grau possível de execução paralela de dados sem a sobrecarga de desempenho de energia. A GPU usa um modelo de execução baseado em cláusula, permitindo que ela execute vários programas de fluxo de controle simultaneamente no mecanismo mais simples.

  • 00:40:00 Nesta seção, a arquitetura do bloco do motor da GPU é discutida. O bloco do motor tem dois componentes principais: compartilhamento de dados local, que permite o compartilhamento de dados entre itens de trabalho em um grupo de trabalho e os elementos de pós-teste, ou núcleos de fluxo, que executam instruções de cláusulas ALU no kernel. O compartilhamento de dados local tem 32 bancos, cada um dos 16 elementos de processamento no mecanismo pode solicitar a leitura ou gravação em palavras de 32 bits do LDS em cada ciclo em endereços arbitrários e os conflitos são detectados pela unidade. As operações atômicas são executadas usando ALUs somente de número inteiro, e as atômicas de ponto flutuante seriam mais complicadas de executar. O elemento de processamento da arquitetura 5870 é um cluster de cinco ALUs idênticos que operam em um pacote de palavras de instrução muito longo de cinco operações empacotadas pelo compilador, com algum conjunto de dependências próprias, e a maioria das operações básicas podem ser executadas.

  • 00:45:00 Nesta seção, o palestrante descreve vários recursos de arquitetura de GPU que ajudam a aumentar a quantidade de compactação que o compilador pode fazer, incluindo a emissão de operações dependentes em um único pacote e o suporte a contadores dependentes com compartilhamento beta global. O compartilhamento beta global é um recurso menos conhecido que está conectado a todo o conjunto de mecanismos de computação no dispositivo e tem uma latência muito menor do que acessar outras memórias. O palestrante também alerta que acessar pixels aleatórios no cache de textura pode causar problemas de desempenho, pois será mais rápido do que fazer acessos à memória global apenas se os dados estiverem agrupados.

  • 00:50:00 Nesta seção, o palestrante responde a perguntas relacionadas à obtenção de ocupação total na arquitetura de GPU. O exemplo dado é que os grupos de trabalho devem consistir em múltiplos de 64 itens de trabalho para obter ocupação total. As frentes de onda e o número de frentes de onda que podem caber em cada núcleo também afetam a ocupação total. O palestrante também menciona que não há versões de precisão total das funções transcendentais geradas pela 5ª Faixa, que são aproximações rápidas que podem ou não ser boas o suficiente, dependendo das necessidades do código. Quando perguntado se existe uma maneira de consultar o tamanho da frente de onda em todos os dispositivos, a resposta é que não existe.

  • 00:55:00 Nesta seção, o palestrante explica o que significa totalmente aglutinado em termos de acessos globais à memória em uma arquitetura de GPU. Essencialmente, isso significa que uma frente de quarto de onda emitirá uma solicitação de memória na qual cada faixa acessará 128 bits consecutivamente de endereços alinhados passando pela unidade de computação. No entanto, existem níveis de eficiência dependendo do tipo de acesso, se é anexado ou separado e se é uma coleta aleatória. O palestrante também esclarece que frente de onda é uma unidade de trabalho composta por 64 itens de trabalho executados em conjunto com uma única instrução, e não é o mesmo que um grupo de trabalho, que é um conjunto de itens de trabalho.

  • 01:00:00 Nesta seção, o palestrante explica o conceito de barreiras na arquitetura da GPU. Se um grupo de trabalho tiver várias frentes de onda, a emissão de uma instrução de barreira sincronizará essas frentes de onda. No entanto, se houver apenas uma frente de onda de trabalho em um grupo, as barreiras serão reduzidas a não operações e não terão significado.
 

AMD Developer Central: série de webinars de programação OpenCL. 4 Programação OpenCL em detalhe



4 - Programação OpenCL em detalhe

Neste vídeo, o palestrante fornece uma visão geral da programação OpenCL, discutindo sua linguagem, plataforma e APIs de tempo de execução. Eles elaboram o modelo de programação que requer paralelização refinada, itens de trabalho e grupos ou threads, sincronização e gerenciamento de memória. O palestrante então discute o algoritmo de n-corpos e sua natureza n-quadrada de ordem computacional. Eles explicam como o código do kernel OpenCL atualiza a posição e a velocidade das partículas na mecânica newtoniana, introduz o cache para armazenar a posição de uma partícula e como o kernel atualiza a posição e a velocidade da partícula usando tipos de dados vetoriais flutuantes. O palestrante também se aprofunda em como o código do host interage com os kernels OpenCL, definindo os parâmetros e argumentos explicitamente, transferindo dados entre o host e a GPU e enfileirando a execução do kernel para sincronização. Por fim, o vídeo explora como modificar o código OpenCL para oferecer suporte a vários dispositivos, sincronizar dados entre as GPUs e definir IDs de dispositivo para matrizes de tamanho médio que as representam.

A segunda parte discute vários aspectos da programação OpenCL. Abrange tópicos como o esquema de buffer duplo para sincronizar a posição de partícula atualizada entre dois arrays, as limitações do OpenCL e a diferença entre ponteiros globais e locais na alocação de memória. Além disso, ele destaca técnicas de otimização para programação OpenCL, incluindo operações vetoriais, acesso controlado à memória e desenrolamento de loop, juntamente com ferramentas disponíveis para analisar a implementação OpenCL, como ferramentas de criação de perfil. O apresentador recomenda o padrão OpenCL como um recurso para programadores OpenCL e fornece URLs para o padrão e o ATI Stream SDK. O vídeo também aborda questões sobre tópicos como compartilhamento de memória, otimização de código, alocação de memória e utilização de unidade de computação.

  • 00:00:00 Nesta seção, o palestrante apresenta os conceitos de OpenCL, discutindo o surgimento de arquiteturas híbridas CPU-GPU e os desafios que elas representam para a programação. O OpenCL fornece uma API independente de plataforma e dispositivo com suporte em todo o setor, e o palestrante descreve as três partes da API OpenCL: a especificação de linguagem, API de plataforma e API de tempo de execução. O modelo de execução é dividido em duas partes: o kernel, que representa o código executável que será executado no dispositivo OpenCL, e o programa host, que faz o gerenciamento de memória e gerencia a execução do kernel em um ou mais dispositivos usando a fila de comandos. A extensão da linguagem C usada para a programação do kernel é baseada na ISO C99 com algumas restrições e adições para dar suporte ao paralelismo.

  • 00:05:00 Nesta seção, o palestrante explica o modelo de programação do OpenCL, que requer paralelização refinada entre threads e sincronização. Itens de trabalho e grupos de trabalho são introduzidos como threads e são agrupados em grupos de trabalho que possuem propriedades especiais em termos de sincronização e acesso à memória compartilhada. O palestrante também cobre o modelo de execução no lado do host, explicando que tudo está reunido em um contexto que inclui uma coleção de dispositivos, objetos de programa, kernels, objetos de memória e a fila de comandos para enfileirar kernels e operações de memória ou transferência de dados . O OpenCL também suporta uma hierarquia de diferentes tipos de memória para refletir a natureza da memória em um sistema híbrido com memória distribuída.

  • 00:10:00 Nesta seção, o palestrante discute a importância de gerenciar a memória e a sincronização ao usar a programação OpenCL. O OpenCL tem um modelo de consistência de memória flexível, tornando responsabilidade do programador gerenciar as transferências de dados e controlar quando os dados são movidos de um dispositivo para outro. A sincronização torna-se essencial ao usar vários dispositivos, e é responsabilidade do programador garantir que os eventos, incluindo a execução do kernel e as transferências de dados, sejam sincronizados corretamente. O palestrante apresenta o uso do Standard CL, que é uma interface simplificada para OpenCL e fornece um contexto padrão pronto para uso, inclui todos os dispositivos e não é interrompido pela funcionalidade OpenCL completa. Além disso, o Standard CL simplifica o gerenciamento de memória por meio do CL Maylock, que aloca memória compartilhável entre dispositivos OpenCL.

  • 00:15:00 Nesta seção, o palestrante discute o algoritmo básico de n-corpos, que modela o movimento de npartículas sujeitas a alguma forma de interação partícula-partícula. O algoritmo envolve o cálculo da força em cada partícula somando as contribuições da interação com todas as outras partículas no sistema. Uma vez que a força em cada partícula é conhecida, a posição e a velocidade da partícula são atualizadas em um pequeno intervalo de tempo. Este processo é repetido para cada partícula, resultando em uma simulação dessas partículas movendo-se sujeitas às forças de interação. O algoritmo é computacionalmente ordenado n-quadrado, o que permite uma boa velocidade usando coprocessadores com limitações na largura de banda de transferência de memória. Todo o algoritmo pode ser escrito em apenas algumas dezenas de linhas de código em C.

  • 00:20:00 Nesta seção, o palestrante explica a implementação do algoritmo n-body através de um loop que acumula a interação entre as partículas. O código do kernel é projetado para fornecer uma implementação razoavelmente padrão usando boas práticas de uma perspectiva OpenCL, mas pode não ser ideal para uma arquitetura específica. O kernel será executado para cada item de trabalho dentro de um espaço de índice, onde cada thread é responsável por atualizar a posição e a velocidade de uma única partícula. O aplicativo possui uma base de índice unidimensional simples com o número de itens de trabalho igual ao número de partículas no sistema. O código do host também é essencial para inicialização, gerenciamento de memória e operações de coordenação em dispositivos OpenCL.

  • 00:25:00 Nesta seção, o palestrante apresenta o código do kernel para atualizar a posição e a velocidade das partículas na mecânica newtoniana. O protótipo do código do kernel é semelhante ao de uma função C, mas com alguns qualificadores que qualificam o espaço de endereçamento e o uso de um esquema de bloqueio. O código do kernel é armazenado em um arquivo separado e usado na compilação just-in-time quando o programa é executado. O palestrante então explica como o código do kernel determina o tamanho e o índice antes de entrar no cálculo real da física. Os IDs de encadeamento global e local também são explicados em detalhes, e o palestrante observa que um loop externo está implícito no código do kernel, pois o kernel será executado automaticamente para cada partícula no sistema.

  • 00:30:00 Nesta seção, o palestrante explica a implementação do kernel OpenCL para o cálculo de força pairwise usando um cache. O kernel armazena em cache uma posição de partícula e conta com os outros itens de trabalho no grupo de trabalho para preencher o cache também. Depois que as 64 posições de partícula são armazenadas em cache, o kernel faz um loop sobre as posições de partícula em cache e implementa o mesmo cálculo de força mostrado no código C, com diferenças notáveis específicas para OpenCL. Isso inclui o uso de um vetor flutuante para a posição da partícula, uma função interna do OpenCL para a raiz quadrada e o armazenamento da massa no quarto componente não utilizado do vetor flutuante por conveniência. O kernel atualiza a posição e a velocidade da partícula em um único relógio usando o tipo de dados do vetor float. Por fim, o palestrante explica a necessidade de barreiras para sincronização durante as operações de preenchimento de cache e loop.

  • 00:35:00 Nesta seção, aprendemos como a nova posição e a nova velocidade são gravadas na memória global em uma nova matriz para evitar a substituição de dados que ainda são necessários para outros threads. Esse esquema de buffer duplo é usado em estágios posteriores para atualizar com segurança a posição da partícula sem encontrar nenhum problema de simultaneidade de thread. Passando para a implementação do código host do kernel, aprendemos como o programa define os parâmetros, aloca memória, inicializa posições e velocidades, constrói e compila o kernel OpenCL, consulta pelo nome o kernel n-body atual necessário, cria um domínio computacional do kernel -dimensional e define os argumentos do kernel explicitamente. No geral, o código mostra como o OpenCL difere dos programas C básicos no fato de que o host executa o kernel por proxy e como os argumentos para o kernel devem ser definidos diretamente.

  • 00:40:00 Nesta seção, o palestrante explica o processo de transferência de dados do host para a GPU usando uma chamada de coletor clm e sincronizando as matrizes no dispositivo (GPU) usando os sinalizadores para chamadas de bloqueio. Eles então discutem as etapas de loop over, introduzindo o valor e o burst que serão usados para fins de diagnóstico e atrasando a configuração dos argumentos dois e três do kernel para buffer duplo. O palestrante observa que a execução do kernel está enfileirada e a chamada de sincronização de espera CL é usada para garantir que todas as execuções do kernel tenham sido concluídas antes de prosseguir. Por fim, eles trazem os dados de volta da GPU para o host usando o buffer de leitura de enfileiramento CL.

  • 00:45:00 Nesta seção, o vídeo discute a modificação do código para dar suporte a vários dispositivos, especificamente executando o código em duas GPUs. A abordagem envolve dividir o trabalho de cálculo de força e atualização de posição de partícula entre as duas GPUs, com uma GPU responsável por metade das partículas. O código do kernel vê pouca troca, com apenas um argumento adicional adicionado ao protótipo chamado "position remote", que aponta para as posições de partícula para partículas que uma determinada GPU não é responsável por atualizar, mas ainda precisa para calcular a força total . Existem mudanças notáveis no lado do host envolvendo gerenciamento de memória e problemas de sincronização que surgem devido ao uso de dois dispositivos.

  • 00:50:00 Nesta seção, a palestra explica as alterações que precisam ser feitas no código do kernel para realizar a simulação de partículas em duas GPUs. O loop sobre as posições das partículas do cache permanece o mesmo de antes, mas antes da linha 21, o loop agora é sobre as posições das partículas locais que a GPU possui. O código é então repetido para partículas remotas que a outra GPU é responsável por atualizar. O código para atualizar a posição e a velocidade da partícula permanece o mesmo. Para modificar o código do host para duas GPUs, a inicialização permanece a mesma, mas também são alocadas matrizes para posições e velocidades de partículas que contêm metade das partículas, com A e B representando as duas GPUs. Um domínio computacional com um espaço de índice de apenas metade do tamanho original é criado e o código para definir estaticamente o ponteiro do argumento para a matriz de velocidade é removido.

  • 00:55:00 Nesta seção, aprendemos como definir o ID do dispositivo para definir em qual GPU os dados serão gravados ao copiar matrizes de tamanho médio para as respectivas GPUs. Também vemos que, para trocar dados entre várias GPUs, precisamos sincronizar as posições atualizadas das partículas de volta às GPUs, alternando as matrizes de partículas de tamanho médio que as representam. Também aprendemos que, para algumas implementações de OpenCL, uma chamada de liberação de CL pode precisar ser introduzida para concorrência verdadeira, mas isso não faz parte do padrão.

  • 01:00:00 Nesta seção, o apresentador analisa o código, que implementa o esquema de buffer duplo para trocar as posições de partículas novas e antigas entre dois arrays. Esse esquema garante que as posições atualizadas das partículas sejam colocadas de volta no array A ou B. Depois que as partículas são sincronizadas com o host, elas precisam ser copiadas de volta para o array maior para reutilizar algumas das funções auxiliares. O apresentador recomenda o padrão OpenCL como um recurso necessário para programadores OpenCL e fornece URLs para o padrão e o ATI Stream SDK. O apresentador também responde a perguntas sobre se o OpenCL pode ser usado para algoritmos como decomposição de valor singular ou fatoração de matriz não negativa e confirma que os dados na memória global na GPU permanecem os mesmos entre as execuções do kernel, o que é crucial para algoritmos mais complexos.

  • 01:05:00 Nesta seção, o vídeo discute as limitações atuais da API OpenCL, que suporta apenas sistemas Unix/Linux e está sendo trabalhada para uma porta Windows. O vídeo também aborda a questão do compartilhamento de memória entre uma GPU e o host, explicando que, embora seja possível, há penalidades de desempenho, tornando típico o uso de memória global alocada na placa de vídeo. Ao alocar memória por meio da API OpenCL, existem maneiras de controlar como isso é tratado, mas parte disso é feito automaticamente no nível de implementação. Além disso, o vídeo explica a diferença entre ponteiros globais e locais na alocação de memória e como a escolha do número ideal de núcleos depende do algoritmo que está sendo executado.

  • 01:10:00 Nesta seção, o palestrante discute várias questões relacionadas à programação OpenCL, como carregar e executar o módulo FTL FGL RX, compatibilidade do padrão Lib CL com ligações C++, otimização de kernels OpenCL para melhoria de desempenho e o uso de CL mem somente leitura ou vedação de leitura/gravação ao alocar buffers de memória. O palestrante também aponta que podem existir ferramentas específicas para edição de kernels OpenCL e otimização para GPUs AMD, além de observar que as técnicas de otimização podem ser muito sutis e exigir muito ajuste.

  • 01:15:00 Nesta seção, o palestrante discute técnicas de otimização para programação OpenCL, incluindo organização de dados para aproveitar as vantagens de operações vetoriais, controle cuidadoso do acesso à memória para melhor desempenho e desenrolamento manual de loops para otimização. Além disso, o uso de tipos de dados complexos e a capacidade de transferir dados entre GPUs sem retornar ao host são específicos da implementação e podem variar dependendo do compilador. O palestrante também menciona que há limitações de tamanho para buffers de memória que dependerão da memória disponível nos dispositivos OpenCL no sistema. Pode ser possível armazenar parâmetros flutuantes mais simples na memória constante para melhor desempenho.

  • 01:20:00 Nesta seção, o palestrante explica que existem ferramentas disponíveis em vários SDKs para analisar a implementação do OpenCL, incluindo ferramentas de criação de perfil para medir a utilização da unidade computacional ou a utilização da transferência de memória. O palestrante também esclarece que o gerenciamento da fragmentação de memória no lado da GPU é específico da implementação e que a implementação deve gerenciá-la adequadamente. Ao usar precisão dupla, não há uma resposta óbvia sobre diminuir o tamanho do grupo de trabalho local para 32 ou 16, pois depende da arquitetura que está sendo usada. O palestrante também menciona a disponibilidade de chamadas de ajuda para obter facilmente informações sobre todos os dispositivos dentro do contexto padrão da GPU.
 

AMD Developer Central: série de webinars de programação OpenCL. 5. Aplicações OpenCL do mundo real



5 - Aplicações OpenCL do mundo real

Neste vídeo, Joachim Deguara fala sobre um aplicativo de processamento de vídeo multistream em que trabalhou, com foco principal na otimização de desempenho. O vídeo aborda vários tópicos, como decodificação de formatos de vídeo, uso de DMA para transferir memória entre CPU e GPU, buffer duplo, execução de kernels, uso de objetos de evento para sincronizar e perfilar operações, interoperabilidade OpenCL-OpenGL, processamento de furtos em vídeos e escolha entre OpenCL e OpenGL ao processar algoritmos. Joachim também discute várias amostras e SDKs disponíveis para aplicativos OpenCL, mas observa que atualmente não há código de exemplo disponível para o aplicativo específico discutido no vídeo.

  • 00:00:00 Nesta seção, Joachim Deguara explica um aplicativo de processamento de vídeo multistream no qual ele trabalhou. O aplicativo envolve abrir vários fluxos de vídeo, decodificá-los, aplicar efeitos de vídeo a eles, combiná-los e, finalmente, apresentar um fluxo de vídeo que é processado repetidamente no final. Joachim Deguara menciona que o desempenho é um foco fundamental para este aplicativo e, para obter uma apresentação em tempo real, é essencial ajustar a decodificação, o processamento e a exibição em uma estrutura de loop que ocorre 30 vezes por segundo ou a taxa de quadros do vídeo de entrada .

  • 00:05:00 Nesta seção, o foco está na decodificação dos formatos de vídeo e na movimentação do quadro para a GPU. Para decodificar o formato do vídeo, é necessário garantir que isso seja feito o mais rápido possível para que não afete o desempenho. Uma maneira de fazer isso é fazer com que a função decode seja executada separadamente do loop principal e, quando chamada, retornar o último quadro. Isso garante que a decodificação seja feita em segundo plano enquanto o loop principal continua ininterrupto. Para mover o quadro para a GPU, são usadas chamadas de API que incluem a especificação da imagem na qual gravar e se a gravação deve ocorrer de forma síncrona ou assíncrona.

  • 00:10:00 Nesta seção, o palestrante discute o DMA (acesso direto à memória) e como ele pode ser usado para transferir memória entre a memória principal do sistema e a memória da GPU sem que a CPU precise copiá-la. O mecanismo DMA lida com essa operação em paralelo, liberando recursos para a CPU e a GPU. A transferência de buffers e imagens pode ser feita de forma assíncrona e requer sinalizadores especiais. No entanto, os dados não podem ser usados imediatamente após uma cópia, portanto, o programa precisa ser reestruturado para aproveitar as vantagens do DMA. O palestrante sugere buffer duplo e processos de loop de reestruturação para evitar a corrupção dos dados atualmente processados ou exibidos. No geral, o DMA pode melhorar muito o desempenho do aplicativo descarregando os ciclos de CPU e GPU.

  • 00:15:00 Nesta seção, o palestrante discute a abordagem de buffer duplo usada no OpenCL para processar e exibir quadros de um vídeo. Essa abordagem envolve armazenar em buffer constantemente dois quadros, A e B, e processar um enquanto o outro está sendo carregado. Isso elimina a necessidade de o tempo de processamento e o tempo de upload serem somados e, em vez disso, leva apenas o tempo máximo necessário para qualquer um dos processos. O palestrante também discute a configuração de argumentos para o kernel, que só precisa ser feito uma vez e pode ser usado para todas as execuções de processamento subseqüentes se os parâmetros não precisarem ser alterados.

  • 00:20:00 Nesta seção, o palestrante discute como executar o kernel e menciona duas maneiras de chamar o processamento, incluindo métodos de bloqueio e não bloqueio. Embora o bloqueio permita uma depuração mais fácil, não é ideal para desempenho, portanto, o locutor apresenta a opção de usar eventos e vetores de eventos para aguardar operações ou configurar gráficos de dependência para várias operações. Ao usar os objetos de evento para sinalizar a conclusão de determinados itens de trabalho, ele pode garantir que a operação de downstream seja iniciada apenas depois que eles forem concluídos, permitindo um processamento mais eficiente.

  • 00:25:00 Nesta seção, o palestrante explica como usar objetos de evento OpenCL para sincronizar operações e como usar perfis de eventos para testes de desempenho. Ao criar o grafo de dependência para filtros, um ponteiro para um evento é passado como último argumento para a Operação Enfileirar, mas o objeto evento é criado dentro do InQ. Isso pode causar confusão, mas permite configurar dependências entre filtros e operações de upload. O palestrante descreve como, com o perfil de evento, é possível obter carimbos de data/hora do evento de quando certos eventos ocorreram no ciclo de vida do evento, como quando aquela operação das referências do evento foi enfileirada, foi enviada, começou a ser executada, e completou a execução. Isso permite a criação de perfil, mantendo todas as operações assíncronas.

  • 00:30:00 Nesta seção do vídeo, o palestrante explica os diferentes estados pelos quais um evento passa ao usar OpenCL, como enfileirado, enviado, em execução e concluído, e como usar dados de perfil de evento e carimbos de data/hora para medir o desempenho e identifique possíveis problemas, como longos tempos de execução para operações ou uploads de dados. O palestrante também discute como aguardar a conclusão dos eventos para garantir a exibição precisa dos fluxos de vídeo com vários filtros e efeitos.

  • 00:35:00 Nesta seção, o palestrante discute a interoperabilidade OpenCL e OpenGL, que permite o compartilhamento de certas informações entre os dois. Essa funcionalidade é opcional e, portanto, nem todas as implementações devem suportá-la. O palestrante enfatiza a importância de verificar a extensão e criar um contexto no OpenCL com determinados sinalizadores para ativar a interoperabilidade OpenCL-OpenGL. A maneira como isso funciona é criando uma imagem OpenCL a partir de uma textura OpenGL que já foi criada, para que os dados não sejam copiados desnecessariamente.

  • 00:40:00 Nesta seção, o palestrante explica como OpenCL e OpenGL podem compartilhar dados de imagem por meio do Interop. Eles cobrem o alvo, o nível NIP e o objeto de textura que são necessários para referenciar a textura Open GL. Depois de criada, a imagem do OpenCl pode ser usada como uma imagem normal do OpenCl, mas os dois programas precisam fazer um aperto de mão para garantir que não interfiram um no outro. O palestrante também responde a uma pergunta sobre como criar transições na renderização de vídeo. Ele diz que isso pode ser feito usando a posição de um furto como uma entrada no filtro. Por fim, o resultado final é entregue ao OpenGL para fins de exibição, o que conclui todas as etapas.

  • 00:45:00 Nesta seção, o palestrante explica como eles processam os deslizamentos em um vídeo observando o marcador de tempo de cada quadro e usando um quadro-chave para interpolar a posição do deslizamento. Eles também respondem a uma pergunta sobre criação de perfil no OpenCL, afirmando que os carimbos de data/hora dependem de um cronômetro externo de alta resolução, mas não de uma chamada para o término do CL. Além disso, o palestrante discute a ordem de execução em dispositivos OpenCL e tempos de execução e confirma que as operações são tratadas em ordem para a maioria dos dispositivos.

  • 00:50:00 Nesta seção, o palestrante explora as diferenças entre OpenCL e OpenGL ao processar algoritmos. A decisão de qual plataforma usar depende das preferências individuais, embora o OpenCL possa ser mais fácil de programar devido à sua estrutura de linguagem abrangente. Em termos de desempenho, o OpenCL pode permitir o processamento de aplicativos que requerem hardware mais complexo; no entanto, há casos em que o uso do sombreamento OpenGL pode levar a um melhor desempenho. Além disso, embora o palestrante não tenha fornecido nenhum código de amostra disponível para o aplicativo específico, há vários exemplos de código no OpenCL SDK da AMD com os quais os usuários podem aprender.

  • 00:55:00 Nesta seção, o palestrante discute vários exemplos e SDKs disponíveis para desenvolvedores de aplicativos OpenCL. As amostras mostram como consultar dispositivos e tempo de execução para obter extensões, além de fornecer exemplos de interoperação OpenCL OpenGL. No entanto, não há nenhum código de amostra atualmente disponível para o aplicativo específico discutido no vídeo, mas isso pode mudar no futuro. O webinar foi concluído e uma gravação será disponibilizada aos participantes.

 

AMD Developer Central: série de webinars de programação OpenCL. 6. Extensões de Fissão de Dispositivo para OpenCL



6 - Extensões de fissão de dispositivos para OpenCL

Neste vídeo, o palestrante aborda vários tópicos relacionados a extensões de fissão de dispositivos para OpenCL. Eles explicam os diferentes tipos de extensões e como a fissão do dispositivo permite que grandes dispositivos sejam divididos em menores, o que é útil para reservar um núcleo para tarefas de alta prioridade ou garantir que grupos de trabalho específicos sejam atribuídos a núcleos específicos. Eles discutem a importância de manter a semântica sequencial ao paralelizar as operações pushback de vetores, usando padrões paralelos para otimizar o processo e criando kernels nativos no OpenCL. O palestrante também demonstra um aplicativo que utiliza fissão de dispositivo para OpenCL e discute a afinidade de memória e o futuro da fissão de dispositivo em outros dispositivos.

  • 00:00:00 Nesta seção, o palestrante discute as extensões em OpenCL, especificamente os três tipos diferentes de extensões: extensões KHR, extensões EXT e extensões de fornecedores. As extensões KHR são aprovadas pelo grupo de trabalho OpenCL e vêm com um conjunto de testes de conformidade. As extensões EXT são desenvolvidas por pelo menos dois membros do grupo de trabalho e não requerem testes de conformidade. Extensões de fornecedores, como CL_AMD_printf, são desenvolvidas por um único fornecedor e só podem ser suportadas por esse fornecedor. A documentação de todas as extensões está disponível no site de registro Chronos OpenCL, permitindo transparência e acessibilidade entre fornecedores.

  • 00:05:00 Nesta seção, o palestrante menciona a extensão de fissão do dispositivo para OpenCL chamada de visão do dispositivo. Esta extensão permite ao usuário dividir dispositivos grandes com muitas unidades de computação em dispositivos OpenCL menores, seja por nome ou por afinidade de memória. Essa divisão pode ajudar a reservar um núcleo para uma tarefa prioritária ou garantir que grupos de trabalho específicos sejam atribuídos a núcleos específicos, como em um sistema baseado em SMP. O palestrante motiva o uso da visão de dispositivo com um exemplo de algoritmos paralelos e contêineres paralelos construídos sobre OpenCL e afirma que essa extensão é atualmente suportada pela AMD e IBM em suas CPUs e dispositivos Cell Broadband.

  • 00:10:00 Nesta seção, o palestrante discute a importância de manter a semântica sequencial ao paralelizar as operações de pushback de vetores. Eles explicam que ao inserir elementos em um vetor durante um loop sequencial, a ordem esperada apareceria em função do loop. No entanto, quando paralelizado, essa ordem é perdida e os elementos podem ser inseridos fora de ordem, então o locutor propõe manter a semântica sequencial da operação de pushback do vetor. Eles então dão um exemplo de como isso pode ser essencial em um aplicativo como uma versão simplificada de um fluxo MPEG-2. Eles concluem apresentando uma função C e discutindo como implementar essas operações paralelas em CPUs.

  • 00:15:00 Nesta seção, o palestrante explica como usar padrões paralelos para otimizar o processo Device Fission Extensions for OpenCL. Eles usam o padrão de pipeline para executar funções em paralelo e introduzir um bloco de dados para ler os dados de entrada para processar um item de trabalho em uma memória local. A abordagem então grava o deslocamento da caixa de correio no grupo de trabalho correspondente para calcular os deslocamentos enquanto preserva a ordem da saída. A ordenação é obtida por meio da comunicação entre grupos de trabalho, em vez de depender do ID global que pode ser executado em uma ordem arbitrária. O padrão de pipeline garante que as funções sejam executadas em paralelo para otimizar o processo.

  • 00:20:00 Nesta seção, o palestrante discute seu pipeline e como eles estão usando o termo "balcão" como uma caixa de correio, já que foram além de apenas contar coisas. Eles explicam que estão passando IDs de grupo para indexação nas caixas de correio e usando memória local e global para cálculos simples. No entanto, eles observam que não há garantias para a execução do grupo de trabalho e explicam como isso pode causar uma situação de impasse. Para resolver esse problema, o palestrante sugere dividir o dispositivo em dois núcleos separados usando a visão do dispositivo, iniciando um grupo de trabalho em cada núcleo e garantindo o progresso. Eles também apresentam um mecanismo importante fornecido pelo OpenCL para execução em um dispositivo host.

  • 00:25:00 Nesta seção, o palestrante discute os benefícios do uso de kernels nativos em OpenCL, que permite a execução de funções C ou C++ arbitrárias. Ele pode oferecer mais flexibilidade na tentativa de diferentes implementações, bem como a capacidade de chamar rotinas de E/S padrão ou outras funções de biblioteca que podem não estar disponíveis no OpenCL. O processo de criação de um kernel nativo em OpenCL envolve a passagem de uma fila de comandos e uma função junto com seus argumentos e objetos de memória. No entanto, deve-se ter cuidado com o armazenamento local de thread, pois a função pode não ser executada no mesmo thread em que foi incluída. O palestrante também apresenta a API de ligações OpenCL C++, que oferece algumas abstrações sobre a API C. O programa começa consultando as plataformas disponíveis e criando um contexto e tipo de dispositivo.

  • 00:30:00 Nesta seção, o palestrante discute o uso de extensões de fissão de dispositivo para OpenCL. Depois que um dispositivo válido é consultado, uma lista de dispositivos é retornada e o primeiro dispositivo é escolhido para suportar a fissão do dispositivo. A fissão do dispositivo é nova na API OpenCL e requer mecanismos de extensão, que permitem que uma partição seja descrita. Eles usam a partição igualmente para particioná-la em dispositivos de unidades de um. As propriedades do subdispositivo são então configuradas e a função de criação de subdispositivos é chamada. Supondo que pelo menos um subdispositivo seja criado, as caixas de correio são criadas e uma fila de comandos é criada para cada dispositivo. Os dispositivos resultantes são exatamente como qualquer outro dispositivo e podem ser usados de forma intercambiável com as bibliotecas existentes. O palestrante então passa para a configuração de kernels OpenCL nativos.

  • 00:35:00 Nesta seção, o palestrante discute as entradas e argumentos necessários para a implementação das extensões Device Fission para OpenCL. O palestrante explica que o buffer de memória para as entradas será dividido em quatro partes, onde os ponteiros serão colocados pelo tempo de execução do FN c. O buffer de memória consistirá em caixas de correio, blocos e transações de cache, e IDs exclusivos serão gerados para cada kernel. O palestrante explica ainda que cada instância do kernel será executada em dispositivos individuais e, depois que todos os eventos forem concluídos, os dados serão gravados com o preenchimento inserido. O próprio kernel incluirá otimizações relacionadas ao bloqueio e armazenamento em cache para garantir uma execução eficiente.

  • 00:40:00 Nesta seção, o palestrante discute a implementação de um aplicativo que utiliza fissão de dispositivo para OpenCL. Eles explicam como o aplicativo funciona usando vários tipos, como entrada/saída, caixas de correio, matrizes de blocos locais, tamanho de bloco e IDs de grupo para indexar conjuntos de dados em paralelo. O aplicativo também implementa otimizações simples de espera ocupada e bloqueio para garantir que tudo seja executado o máximo possível em paralelo. Ao utilizar a fissão do dispositivo, a implementação deste aplicativo mostra o potencial para alcançar aumentos de velocidade na CPU com pouca ou nenhuma operação ALU, o que pode aumentar ainda mais com a implementação de vetores mais amplos no futuro. O palestrante também discute as outras aplicações e casos de uso para fissão de dispositivos, como divisão em relação ao infinito e sistemas espaciais Numa.

  • 00:45:00 Nesta seção, o palestrante discute os benefícios da afinidade de memória no OpenCL, que permite a associação precisa de buffers com um determinado dispositivo. Isso pode levar a uma melhor localidade de cache e desempenho aprimorado, evitando contenção e compartilhamento negativo. O esquema de caixa de correio usado no OpenCL pode ser estendido para oferecer suporte a várias iterações, permitindo um loop que inicia o pipeline em cascata repetidas vezes. O palestrante também menciona a disponibilidade de recursos na zona OpenCL em developer.amd.com, onde os interessados podem encontrar mais informações sobre OpenCL, incluindo webinars, apresentações anteriores e um próximo encontro sobre computação heterogênea. O palestrante também sugere a possibilidade de suportar a fissão do dispositivo na GPU no futuro, o que reservaria uma parte do núcleo para tarefas de alta prioridade e garantiria melhor desempenho.

  • 00:50:00 Nesta seção do vídeo, o palestrante discute o futuro da fissão de dispositivos em direção a outros dispositivos. Atualmente, apenas AMD e IBM oferecem suporte a extensões de fissão de dispositivo para OpenCL, mas outros fornecedores demonstraram interesse na proposta. A questão levantada é se bibliotecas matemáticas como BLAS e FFT serão suportadas, e o palestrante confirma que eles estão trabalhando em implementações OpenCL de BLAS e diferentes variantes e implementações para álgebra linear que serão apresentadas em uma biblioteca estilo FFT.
 

AMD Developer Central: série de webinars de programação OpenCL. 8. Técnicas de Otimização: Convolução de Imagens



Neste vídeo Udeepta D. Bordoloi discute as técnicas de otimização em convolução de imagens.

 

AMD Developer Central: série de webinars de programação OpenCL. 7. Hidrodinâmica de partículas suavizadas




7 - Hidrodinâmica de Partículas Alisadas

Este vídeo discute a hidrodinâmica de partículas suavizadas (SPH), uma técnica para resolver equações de dinâmica de fluidos, especificamente as equações de Navier-Stokes. O vídeo explica os diferentes termos nas equações, incluindo os termos de densidade, pressão e viscosidade, e como eles são aproximados usando um núcleo de suavização. O algoritmo numérico usado para SPH, bem como o uso de indexação espacial e Interop, também é discutido. O palestrante explica o processo de construção de um índice espacial e um mapa de vizinhos e como a física é calculada. O vídeo convida os espectadores a baixar e usar o programa e discute as limitações da simulação. O palestrante responde a perguntas do público sobre o desempenho da GPU, comportamento incompressível e uso de imagens em cache.

  • 00:00:00 Nesta seção, Alan Hierich, membro sênior da equipe técnica da AMD, fornece uma visão geral da dinâmica de fluidos computacional, especificamente a hidrodinâmica de partículas suaves (SPH). O SPH foi originalmente usado para cálculos de astrofísica, mas tornou-se bastante popular em videogames e simulações. A técnica é usada para resolver as equações de Navier-Stokes, que são equações diferenciais parciais formuladas em 1900 e são a base da maioria dos trabalhos de dinâmica de fluidos hoje. Allen explica a definição de fluidos e fornece uma explicação intuitiva de como eles funcionam, com foco em líquidos e gases. Ele também descreve que os fluidos são geralmente descritos pelas equações de Navier-Stokes, e as equações incompressíveis de Navier-Stokes governam fluidos como a água em velocidades e temperaturas normais.

  • 00:05:00 Nesta seção, o palestrante explica as equações que regem os fluidos, conhecidas como equações de Navier-Stokes. A equação do movimento representa a mudança na velocidade em função da gravidade, pressão e viscosidade, enquanto a equação da continuidade da massa afirma que a massa não é criada nem destruída. Os fenômenos que governam um fluido são gravidade, pressão e velocidade, e a viscosidade é a viscosidade do fluido, que determina a probabilidade de as partículas do fluido viajarem na mesma direção. Também é discutido o termo de aceleração convectiva, que descreve a aceleração de um fluido conforme ele se move através de uma abertura menor, como um bocal em uma mangueira de jardim. O palestrante convida o público a baixar e brincar com o programa que simula fluidos em uma caixa demonstrada.

  • 00:10:00 Nesta seção, o palestrante explica os diferentes termos da equação de movimento para dinâmica de fluidos, incluindo aceleração convectiva, gradiente de pressão e viscosidade. A pressão é definida como a diferença entre a densidade real do fluido em um ponto e a densidade de repouso. O termo de viscosidade, que é o último termo do lado direito da equação de movimento, difunde o momento do sistema, resultando em um estado onde a velocidade é equivalente em todos os locais. Há também uma equação de continuidade de massa, del dot V igual a 0, o que implica que a massa não é criada nem destruída nas equações incompressíveis. Por fim, para representar a dinâmica do sistema, o falante usa a derivada material da equação para obter a equação do movimento de uma partícula.

  • 00:15:00 Nesta seção, o vídeo discute a técnica de hidrodinâmica de partículas suavizadas (SPH) para resolver as equações de Navier-Stokes incompressíveis simplificadas introduzidas na seção anterior. A técnica SPH foi introduzida pela primeira vez em 1992 para estudar astrofísica e galáxias, mas também pode ser usada para equações de fluidos. Envolve a introdução de representações de núcleo de suavização de quantidades, que são como funções de base que nos permitem aproximar qualquer quantidade por um somatório da quantidade em pontos próximos multiplicados por uma função de ponderação. A técnica SPH é usada para aproximar os termos de densidade e gradiente de pressão nas equações de Navier-Stokes. O vídeo também menciona que as equações de Navier-Stokes são numericamente sensíveis à escala e que os cálculos são feitos em uma escala menor antes de serem expandidos para a escala espacial regular para mover as partículas no espaço.

  • 00:20:00 Nesta seção, o palestrante explica os três principais termos que são aproximados em Smoothed Particle Hydrodynamics (SPH), que são os termos de densidade, pressão e viscosidade. Para calcular a densidade, o programa calcula a massa de partículas em vários pontos e multiplica isso pelo gradiente de um núcleo de suavização. O termo de pressão é então calculado usando uma quantidade escalar de pressão dividida pela densidade, que é multiplicada pelo gradiente do núcleo de suavização. Por outro lado, o termo de viscosidade é aproximado usando um coeficiente escalar que determina o nível de viscosidade do fluido e a diferença de velocidade entre dois pontos dividida pela densidade do ponto J. O palestrante também explica as propriedades do núcleo de suavização, que é usado na simulação SPH e como ele soma um sobre uma esfera de raio H.

  • 00:25:00 Nesta seção, o palestrante discute o algoritmo numérico usado para Smoothed Particle Hydrodynamics (SPH). O algoritmo envolve a computação de densidade, pressão, gradiente de pressão, termo viscoso e aceleração, que são então usados para escalonar as velocidades e posições das partículas. O palestrante explica que o algoritmo inicial envolve testar as interações de todas as partículas contra todas as partículas, o que é correto, mas não rápido o suficiente. Assim, é introduzido um algoritmo melhor, que divide o espaço em voxels, permitindo interações apenas com partículas dentro do raio de interação. Além disso, um subconjunto de partículas é escolhido aleatoriamente para calcular as interações em vez de considerar todas as partículas, o que produz um programa eficiente.

  • 00:30:00 Nesta seção, o palestrante discute o uso de indexação espacial para computar apenas interações com um número limitado de partículas em simulações OpenCL, bem como a importância de usar Interop para compartilhar buffers de dados com um sistema gráfico. Embora o Interop permita a renderização diretamente do buffer da GPU e economize espaço na memória gráfica, sem ele o programa teria que copiar os dados para a memória do host e vice-versa, tornando a simulação significativamente mais lenta. O palestrante explica as modificações necessárias para usar o Interop, incluindo a criação de um contexto diferente, e apresenta o conjunto de buffers necessários para a simulação, incluindo índice de partículas para classificação. Apesar de discutir a importância do Interop, o programa apresentado não o utiliza, o que torna a simulação mais lenta.

  • 00:35:00 Nesta seção, o palestrante discute os vários kernels usados no algoritmo Smoothed Particle Hydrodynamics. O primeiro kernel é "partículas de hash", que associa partículas a um voxel. Em seguida, os kernels "sort" e "sort post pass" classificam as partículas em voxels e as organizam para a construção do índice espacial. Em seguida, os kernels "index" e "index post pass" constroem um índice espacial de voxels para partículas. Depois disso, o kernel de "vizinhos finos" decide quais vizinhos irão interagir entre si. Por fim, os núcleos de "computação da pressão de densidade", "computação da aceleração" e "integração" calculam as interações e a física entre as partículas. O palestrante explica que a classificação radix é usada na versão GPU do código, enquanto a classificação Q é usada na versão CPU do código.

  • 00:40:00 Nesta seção, o vídeo explica o processo de construção de um índice espacial de voxels para partículas em Smoothed Particle Hydrodynamics (SPH). O kernel usa uma busca binária para identificar a partícula de menor número em cada voxel e deixa um valor negativo em voxels que não contêm partículas. A pós-passagem do índice então preenche um valor de índice para voxels vazios copiando o valor do próximo voxel não vazio no índice da célula da grade. Uma vez que a indexação é feita, o programa constrói um mapa vizinho procurando na região local de dois por dois por dois voxels que cercam cada partícula. Para eliminar o viés, o programa gera um deslocamento aleatório em cada voxel e alterna a direção da busca. O kernel então seleciona as primeiras 32 partículas dentro do raio de interação e as adiciona ao mapa vizinho.

  • 00:45:00 Nesta seção, o palestrante explica como eles calcularam a física construindo um mapa vizinho, que permite interagir com 32 partículas. Eles repassam as equações usadas para aproximar densidade e pressão, calculam os termos de aceleração e combinam tudo para determinar a aceleração total. A velocidade e a posição são então avançadas através da integração numérica, com condições de contorno estabelecidas para evitar que as partículas escapem da caixa. O palestrante incentiva os espectadores a baixar e brincar com o código-fonte e enfatiza que, embora existam muitos métodos lentos para resolver as equações de Navier-Stokes, lento não significa necessariamente bom.

  • 00:50:00 Nesta seção do vídeo, o palestrante explica a etapa de atualização da simulação, onde a velocidade é integrada à sua nova posição antes de atualizar a posição. A atualização da velocidade é explícita, enquanto a atualização da posição é semi-implícita, usando o valor da velocidade no próximo intervalo de tempo. A simulação está em flutuação para fins de desempenho, mas se forem necessárias alta fidelidade e precisão, o uso de double seria recomendado. O algoritmo é totalmente paralelizável, mas as compensações do particionamento espacial precisam ser levadas em consideração. Por fim, o palestrante responde a perguntas sobre o uso de Interop com várias GPUs, simulando turbulência e o número máximo prático de partículas na simulação.

  • 00:55:00 Nesta seção, o palestrante responde algumas perguntas do público. Eles explicam que a limitação prática de sua simulação é a taxa de desempenho, que depende da classe de GPU e CPU utilizada. Eles também mencionam que, embora sua simulação seja baseada em equações incompressíveis, eles não estão resolvendo explicitamente a condição de incompressibilidade, o que pode limitar seu comportamento compressível. O palestrante também responde a uma pergunta sobre por que eles usaram buffers em vez de memória de imagem em cache, afirmando que, na época em que desenvolveram o programa, não viram nenhuma vantagem de desempenho no uso de imagens em cache. No entanto, eles mencionam que o OpenCL fornecerá suporte para buffers em cache no futuro e que eles podem alterar o programa para suportá-los. No geral, o palestrante convida o público a baixar e usar o programa da maneira que quiser, pois não há limitações para ele.
 

AMD Developer Inside Track: Como otimizar a convolução de imagens



Como otimizar a convolução da imagem

Este vídeo discute vários métodos para otimizar a convolução da imagem, incluindo o uso de compartilhamento de dados local, otimização de constantes e uso de áreas locais maiores para melhorar a eficiência. O palestrante enfatiza a importância de minimizar o tempo de processamento na convolução da imagem para melhorar o desempenho geral e destaca um novo método de reutilização de dados usando a memória local. O vídeo oferece sugestões para etapas de otimização, como usar texturas ou óbvias, usar a força do pensamento e usar as opções de passagem para o contador. Um artigo passo a passo sobre como otimizar as técnicas de convolução de imagem está disponível no site do desenvolvedor da AMD.

  • 00:00:00 Nesta seção, Udeepta Bordolo da equipe de gráficos da AMD explica o conceito de convolução de imagem, que envolve fazer uma soma ponderada sobre uma área da imagem de entrada para gerar um pixel de imagem de saída. Ele usa OpenCL e uma GPU 5870 para realizar a otimização, trabalhando gradualmente a partir do código de correlação básico. Espelhamento e uso de LDS (Local Data Share) são alguns dos métodos de otimização utilizados, resultando em uma redução significativa no tempo de execução.

  • 00:05:00 Nesta seção, o palestrante discute a otimização da convolução da imagem em um programa que funciona para todos os tamanhos de filtro e todos os tamanhos de entrada. Ele se concentra no uso de áreas locais para melhorar o compartilhamento de dados e reduzir o tempo de espera. Ao interpretar constantes e entradas como valores de 128 bits, o compilador e o gênio podem interpretar o código com mais facilidade e reduzir o tempo de processamento. Ele mostra como otimizar constantes e usar áreas locais maiores pode melhorar muito a eficiência na convolução de imagens. No geral, o palestrante enfatiza a importância de encontrar maneiras de minimizar o tempo de processamento na convolução da imagem para melhorar o desempenho geral.

  • 00:10:00 Nesta seção, o palestrante discute como otimizar a convolução da imagem determinando o tamanho do filtro e como alterá-lo para diferentes máscaras. O palestrante observa que a aplicação de otimização em momentos diferentes pode afetar o desempenho, mas pode ajudar a encontrar problemas inesperados. O palestrante também discute a execução do mesmo número de elementos para uma imagem de entrada de 2k por 2k com dados de força total, o que resultou em um formato de dados mais eficiente. Além disso, o palestrante destaca um novo método de reutilização de dados em vez de usar o motor usando a memória local, conhecida como LDS em hardware.

  • 00:15:00 Nesta seção, o palestrante fala sobre a otimização de técnicas de convolução de imagens. Eles carregam todas as entradas, atrasam-nas por um grupo específico e, em seguida, trabalham fora do óbvio. Eles usam o dinheiro como o conhecem e param de usar o LDS para tentar usar texturas. Eles realizam um experimento com resolução de 2K por 2K e diferentes tamanhos de filtro, e obtêm o número mais rápido ao usar texturas. Eles sugerem as etapas de otimização do uso de texturas ou óbvias, usando a força do pensamento e usando as opções de passagem para o contador. Eles também sugerem usar o monstro do dinheiro quando possível. Eles publicaram um artigo passo a passo sobre como otimizar as técnicas de convolução de imagem no site do desenvolvedor da AMD, ao qual estão vinculados ao lado do vídeo.
How to Optimize Image Convolution
How to Optimize Image Convolution
  • 2013.05.28
  • www.youtube.com
Udeepta Bordoloi, MTS Software Engineer in the Stream Computing Group Udeepta Bordoloi walks though several different ways to optimize an image convolution a...
 

AMD Developer Central: visão geral técnica do OpenCL. Introdução ao OpenCL



AMD Developer Central: visão geral técnica do OpenCL. Introdução ao OpenCL

Neste vídeo, Michael Houston fornece uma visão geral do OpenCL, um padrão da indústria para computação paralela de dados visando CPUs multi-core, dispositivos móveis e outras formas de silício. O OpenCL visa unificar implementações proprietárias anteriormente concorrentes, como CUDA e Brook+, que simplificarão o desenvolvimento para fornecedores de software independentes. Ele oferece uma divisão entre o código executado no dispositivo e o código que gerencia o dispositivo usando um sistema de filas projetado para feedback com os desenvolvedores de jogos. O OpenCL foi projetado para funcionar bem com APIs gráficas, criando uma linguagem de computação onipresente que pode ser usada para vários aplicativos, como edição de fotos e vídeos, bem como para sistemas de inteligência artificial, modelagem e física. O apresentador também discute o uso do OpenCL para renderização de Hollywood e espera ver mais trabalhos nessa área.

  • 00:00:00 Nesta seção, Mike Houston explica o propósito do OpenCL como um padrão da indústria para computação paralela de dados, visando CPUs multi-core, dispositivos móveis e outras formas de silício. O OpenCL visa unificar implementações proprietárias anteriormente concorrentes, como CUDA e Brook+, o que simplificará o desenvolvimento para fornecedores de software independentes. Embora haja um dialeto diferente e pequenas diferenças no OpenCL, a transição de outras linguagens paralelas de dados, como CUDA, é direta e rápida. O OpenCL também oferece uma divisão entre o código executado no dispositivo e o código que gerencia o dispositivo usando um sistema de filas projetado para feedback com os desenvolvedores de jogos. Ele foi projetado para funcionar bem com APIs gráficas, criando uma linguagem de computação onipresente para o espaço do consumidor em aplicativos como edição de fotos e vídeos.

  • 00:05:00 Nesta seção, o palestrante explica alguns dos usos iniciais do OpenCL, que incluem o processamento de imagens ou vídeo de alta resolução e a execução de antivírus. Além disso, a tecnologia é útil para sistemas de inteligência artificial, sistemas de modelagem, física, pós-processamento e aceleração de iluminação e renderização para filmes. O palestrante espera ver mais trabalhos sobre o uso do OpenCL para renderização de Hollywood, entre outras coisas.
Introduction to OpenCL
Introduction to OpenCL
  • 2013.05.29
  • www.youtube.com
Michael Houston, GPG System Architect Learn about OpenCL, what the transition to OpenCL will be like, what applications are ideal for OpenCL and what impact ...
 

AMD Developer Central: Episódio 1: O que é OpenCL™?



AMD Developer Central: Episódio 1: O que é OpenCL™?

Este vídeo fornece uma introdução ao OpenCL e seus objetivos de design, que se concentram em alavancar vários processadores para acelerar cálculos paralelos em vez de sequenciais. O OpenCL permite a escrita de código portátil para diferentes processadores usando kernels, dimensões globais e locais e grupos de trabalho. Itens de trabalho e grupos de trabalho podem colaborar compartilhando recursos, mas a sincronização entre itens de trabalho em diferentes grupos de trabalho não é possível. As dimensões ótimas do problema variam para diferentes tipos de processamento e é importante escolher as melhores dimensões para obter o melhor desempenho. O OpenCL pode utilizar totalmente os recursos de um sistema expressando tarefas e paralelismo de dados juntos usando o modelo de evento OpenCL.

  • 00:00:00 Nesta seção, Justin Hensley discute os fundamentos do OpenCL e seus objetivos de design, que se concentra principalmente em alavancar CPUs, GPUs ou qualquer outro processador, como o mecanismo de banda larga celular ou DSPs, para acelerar cálculos paralelos em vez de sequenciais, resultando em acelerações dramáticas. O OpenCL permite escrever código portátil para rodar em qualquer tipo de processador, como CPUs e GPUs AMD, usando kernels, que são semelhantes às funções C usadas para explorar o paralelismo, e programas que são coleções de kernels e outras funções, com aplicativos executando instâncias do kernel usando filas que são enfileiradas e executadas em ordem ou fora de ordem. As dimensões globais e locais no OpenCL definem o alcance da computação, enquanto o objetivo do OpenCL é usar dispositivos altamente paralelos para acelerar a computação simultaneamente, permitindo que grupos de trabalho locais colaborem compartilhando recursos porque os itens de trabalho globais devem ser independentes, com sincronização possível. dentro de um grupo de trabalho.

  • 00:05:00 Nesta seção, aprendemos sobre itens de trabalho e grupos de trabalho e como o OpenCL nos permite sincronizar entre itens de trabalho dentro de um grupo de trabalho usando barreiras ou cercas de memória. No entanto, itens de trabalho em diferentes grupos de trabalho não podem sincronizar uns com os outros. As dimensões ótimas do problema também variam para diferentes tipos de processamento, e é importante escolher as melhores dimensões para o problema em questão para obter o melhor desempenho. No OpenCL, também é possível expressar paralelismo de tarefa executando um único item de trabalho como uma tarefa usando o modelo de evento OpenCL. Ao permitir que tarefas e paralelismo de dados funcionem juntos, o OpenCL pode utilizar totalmente a capacidade do sistema.
Episode 1: What is OpenCL™?
Episode 1: What is OpenCL™?
  • 2013.05.27
  • www.youtube.com
In this video, you learn what OpenCL™ is and why it was designed the way itis. We go through design goals and the execution model of OpenCL™. Topicscovered i...