Avanços nas Representações de Computação de Alto Desempenho
Nova representação melhora as previsões para aplicações de HPC em vários sistemas de hardware.
― 7 min ler
Índice
- O que é uma Representação de Programa?
- A Necessidade de Representações Melhoradas
- Nossa Abordagem
- Por que Usar Redes Neurais de Grafo?
- Como Montamos Nosso Conjunto de Dados
- Experimentando com Nossa Nova Representação
- Resultados dos Nossos Experimentos
- Conclusão
- Direções Futuras
- Fonte original
- Ligações de referência
Computação de Alto Desempenho (HPC) é uma área super importante na computação que foca em usar computadores potentes pra resolver problemas complexos. Esses problemas geralmente aparecem em pesquisas científicas, simulações e análise de grandes dados. Com o avanço da tecnologia, mais desenvolvedores estão interessados em criar aplicações que rodem bem em vários tipos de sistemas de computação, incluindo Unidades de Processamento Gráfico (GPUs) e Unidades de Processamento Central (CPUs).
Essa busca por eficiência faz com que os desenvolvedores frequentemente usem ferramentas e modelos de programação como o OpenMP, que facilita a escrita de código paralelo. O código paralelo permite que as tarefas rodem ao mesmo tempo, o que pode acelerar bastante os tempos de processamento. Mas, descobrir como tirar melhor proveito dos diferentes sistemas de computação ainda pode ser desafiador.
A introdução de métodos de Aprendizado de Máquina (ML) ofereceu novas formas de otimizar aplicações HPC. No entanto, os métodos atuais às vezes não conseguem capturar totalmente recursos importantes do código paralelo que ajudam a melhorar o desempenho.
O que é uma Representação de Programa?
Em programação, uma representação é como a gente visualiza a estrutura e o comportamento do código. Assim como um arquiteto usa plantas para projetar um edifício, os desenvolvedores de software usam representações de programa pra entender como seu código funcionará.
Uma representação comum é a Árvore de Sintaxe Abstrata (AST). Uma AST quebra o código em uma estrutura de árvore onde cada nó representa uma parte do código. No entanto, as ASTs tradicionais têm limitações quando se trata de capturar as complexidades dos programas paralelos – aqueles projetados pra rodar em múltiplos núcleos ou processadores ao mesmo tempo.
A Necessidade de Representações Melhoradas
A maioria das representações existentes foca em programas de thread única, o que significa que elas não refletem adequadamente como os programas paralelos operam. Essa falta de detalhes pode dificultar a eficiência dos métodos de otimização que usam essas representações.
Pra resolver isso, podemos aprimorar as ASTs com informações adicionais. Isso pode incluir recursos específicos de laços e condicionais que são fundamentais para o processamento paralelo. Ao adicionar essas informações, podemos criar um novo tipo de representação de programa que pode dar um suporte melhor à otimização de desempenho.
Nossa Abordagem
A gente apresenta uma nova maneira de representar programas chamada representação em grafo ponderado. Essa representação se baseia na AST tradicional e acrescenta arestas extras, que são como conexões entre diferentes partes do código. Cada aresta pode carregar pesos que representam com que frequência certas partes do código serão usadas durante a execução.
Adicionando Arestas à AST: Ao introduzir novas arestas, conseguimos ilustrar as relações entre diferentes componentes do código de forma mais clara. Por exemplo, quando temos um laço, conseguimos mostrar com que frequência o laço vai rodar e quais condições afetam sua execução.
Usando Pesos: Os pesos nessas arestas fornecem uma forma de indicar quantas vezes um pedaço específico de código será executado. Isso é crucial pra entender o desempenho, porque nem todas as partes do código são usadas de maneira igual.
Usando essa nova representação, podemos alimentá-la em Redes Neurais de Grafo (GNNs), que são modelos especializados que podem aprender com estruturas de grafo. Isso nos permite fazer previsões melhores sobre como diferentes códigos vão se comportar em vários sistemas de hardware.
Por que Usar Redes Neurais de Grafo?
As GNNs são ferramentas poderosas pra aprender com dados estruturados como grafos. Como nossa nova representação se parece com um grafo, podemos aproveitar as GNNs pra encontrar padrões e relações que métodos tradicionais podem perder. Para aplicações HPC, isso significa que conseguimos prever com precisão quanto tempo diferentes pedaços de código vão levar pra rodar em diferentes tipos de hardware.
Como Montamos Nosso Conjunto de Dados
Criar um conjunto de dados pra treinar nossa GNN é um passo crucial. Precisamos de uma coleção de códigos diferentes junto com informações sobre seu desempenho. Isso envolve várias etapas importantes:
Gerando Diferentes Kernels: Pra nossos experimentos, criamos várias versões de aplicações chamadas kernels. Cada kernel é uma tarefa específica que o código vai executar. Geramos versões diferentes modificando como eles podem ser executados em CPUs e GPUs.
Usando OpenMP Advisor: Essa ferramenta ajuda a produzir diferentes variantes dos nossos kernels. Ela permite que a gente crie kernels que podem usar recursos paralelos de forma eficaz.
Coletando Dados de Execução: Depois de gerar os kernels, rodamos cada um deles e medimos quanto tempo leva pra executar. Esses dados de execução são essenciais pra ensinar nossa GNN como fazer previsões.
Criando um Conjunto de Dados Robust: No final, acabamos com milhares de kernels únicos e seus dados de execução correspondentes, formando um conjunto rico pra treinamento.
Experimentando com Nossa Nova Representação
Uma vez que temos nosso conjunto de dados pronto, podemos começar a treinar nosso modelo GNN usando a representação em grafo ponderado dos códigos. O processo de treinamento envolve vários desafios, mas podemos usar os dados que coletamos pra melhorar as previsões.
Métricas de Avaliação
Pra avaliar quão bem nosso modelo se sai, precisamos definir métricas pra medir sua precisão. Uma métrica comum é o Erro Quadrático Médio (RMSE), que compara os tempos de execução previstos com os tempos reais que coletamos. Um RMSE mais baixo indica que nosso modelo está fazendo previsões precisas.
Resultados dos Nossos Experimentos
Depois de treinar nosso modelo, realizamos uma série de experimentos usando diferentes tipos de hardware. Avaliamos quão bem nossa representação funciona em prever o tempo de execução de aplicações tanto em GPUs quanto em CPUs.
Melhorando a Precisão das Previsões
Descobrimos que nossa representação em grafo ponderado ajuda a fazer previsões mais precisas em comparação com representações tradicionais. Ao incorporar arestas e pesos adicionais, conseguimos capturar melhor a complexidade do código paralelo, levando a uma redução significativa no erro de previsão.
Desempenho em Diferentes Hardwares
Analisamos também quão bem nosso modelo generaliza entre vários tipos de hardware. Os resultados indicam que as previsões permanecem estáveis e precisas, independente de o código rodar em uma GPU ou em uma CPU. Essa versatilidade é crucial, já que aplicações HPC frequentemente precisam rodar em múltiplos tipos de sistemas.
Conclusão
Resumindo, estabelecemos uma nova abordagem pra representar aplicações HPC que melhora as ASTs tradicionais com grafos ponderados. Essa nova representação captura características vitais do código paralelo, levando a previsões aprimoradas do desempenho em tempo de execução.
Nossos experimentos confirmam que essa abordagem pode apoiar eficazmente os desenvolvedores na otimização de suas aplicações em diversas plataformas de hardware. À medida que continuamos a refiná-la, ela promete explorar mais otimizações em diferentes ambientes de programação paralela.
Direções Futuras
Olhando pra frente, planejamos pesquisar várias vertentes pra expandir esse trabalho. Isso inclui explorar como nossa representação pode melhorar outras áreas da programação paralela, como otimização de estratégias de agendamento, tamanhos de bloco de laços e mais. Além disso, queremos adaptar nossa estrutura pra ser usada com outros modelos de programação paralela, ampliando ainda mais seu alcance e aplicabilidade no campo da computação de alto desempenho.
Com esses esforços, aspiramos contribuir para a evolução e melhoria contínua das aplicações HPC, tornando-as mais eficientes e eficazes em enfrentar os desafios crescentes na computação.
Título: ParaGraph: Weighted Graph Representation for Performance Optimization of HPC Kernels
Resumo: GPU-based HPC clusters are attracting more scientific application developers due to their extensive parallelism and energy efficiency. In order to achieve portability among a variety of multi/many core architectures, a popular choice for an application developer is to utilize directive-based parallel programming models, such as OpenMP. However, even with OpenMP, the developer must choose from among many strategies for exploiting a GPU or a CPU. Recently, Machine Learning (ML) approaches have brought significant advances in the optimizations of HPC applications. To this end, several ways have been proposed to represent application characteristics for ML models. However, the available techniques fail to capture features that are crucial for exposing parallelism. In this paper, we introduce a new graph-based program representation for parallel applications that extends the Abstract Syntax Tree to represent control and data flow information. The originality of this work lies in the addition of new edges exploiting the implicit ordering and parent-child relationships in ASTs, as well as the introduction of edge weights to account for loop and condition information. We evaluate our proposed representation by training a Graph Neural Network (GNN) to predict the runtime of an OpenMP code region across CPUs and GPUs. Various transformations utilizing collapse and data transfer between the CPU and GPU are used to construct the dataset. The predicted runtime of the model is used to determine which transformation provides the best performance. Results show that our approach is indeed effective and has normalized RMSE as low as 0.004 to at most 0.01 in its runtime predictions.
Autores: Ali TehraniJamsaz, Alok Mishra, Akash Dutta, Abid M. Malik, Barbara Chapman, Ali Jannesari
Última atualização: 2023-04-07 00:00:00
Idioma: English
Fonte URL: https://arxiv.org/abs/2304.03487
Fonte PDF: https://arxiv.org/pdf/2304.03487
Licença: https://creativecommons.org/licenses/by/4.0/
Alterações: Este resumo foi elaborado com a assistência da AI e pode conter imprecisões. Para obter informações exactas, consulte os documentos originais ligados aqui.
Obrigado ao arxiv pela utilização da sua interoperabilidade de acesso aberto.