Simple Science

Ciência de ponta explicada de forma simples

# Informática # Desempenho # Arquitetura de Hardware

Uma nova ferramenta pra checar a performance da memória

Essa ferramenta ajuda os desenvolvedores a analisar o uso de memória de forma eficiente.

Ashwin Poduval, Hayden Coffey, Michael Swift

― 9 min ler


Ferramenta de Desempenho Ferramenta de Desempenho de Memória Revelada desempenho de memória eficiente. Uma ferramenta leve para análise de
Índice

O desempenho da memória é um grande problema em computadores modernos. Nos últimos anos, vários pesquisadores tentaram resolver isso usando novas tecnologias como CXL e HBM, além de processar mais perto da memória. Os desenvolvedores precisam saber como os programas com os quais estão trabalhando se saem para aproveitar ao máximo esses sistemas. Infelizmente, as ferramentas atuais para checar o desempenho não são muito boas. Elas costumam medir as coisas de um jeito muito amplo, não ajudam na depuração, deixam tudo mais lento ou dependem demais do hardware. Com as conexões mais próximas entre a memória e computação em muitos novos sistemas, há uma chance de melhorar o suporte para os desenvolvedores.

Criamos uma ferramenta de verificação de desempenho de memória que se baseia no sistema de compilação LLVM. Nossa ferramenta permite que os desenvolvedores marquem partes específicas do código, possibilitando checagens focadas em seções importantes. Ela também pode usar ferramentas de medição de hardware quando disponíveis, além das verificações de software. Antes do programa rodar, ela coleta dados sobre os tipos de Instruções no código e depois adiciona checagens em tempo de execução para estimar quanto de memória está sendo usada. Esse método mantém o tempo extra adicionado bem baixo, com uma sobrecarga média de menos de 10% e uma precisão de 93%. A forma como configuramos nossa checagem é flexível o suficiente para funcionar com diferentes tipos de sistemas.

Por que a Memória É Importante

A movimentação de dados pode deixar um sistema bem mais lento e consumir muita energia. Já sugeriram várias maneiras de ajudar com esse problema. Por exemplo, trabalhos recentes focaram em usar CXL para aumentar a Largura de banda e capacidade da memória. Enquanto isso, vários estudos analisaram o processamento em sistemas de memória para trazer a computação mais perto da memória. Esses tipos de sistemas geralmente usam tecnologias de memória empilhada em 3D, como Memória de Alta Largura de Banda (HBM) e Hybrid Memory Cube (HMC), junto com processadores especializados.

No entanto, esses sistemas podem não acelerar aplicativos inteiros. Em vez disso, os desenvolvedores precisam encontrar as partes do código que são pesadas em dados e que podem se beneficiar da velocidade extra da memória. Mesmo os sistemas baseados em CXL, que não exigem mover o código, precisam que alguém (geralmente o sistema operacional) decida onde colocar os dados em diferentes áreas de memória.

O código que lida com muitos dados deve utilizar ao máximo a alta velocidade da memória tentando criar várias acessos paralelos. Isso significa usar técnicas como vetorização e multithreading para acessar a memória de diferentes canais ao mesmo tempo. No entanto, escrever um código que faça isso pode ser difícil. Por exemplo, um desenvolvedor pode escrever um código que faz com que algumas threads trabalhem mais do que outras ou usem estruturas de dados que atrasam tudo por causa de problemas de sincronização.

Casos de Uso

Nosso sistema ajuda focando no que chamamos de regiões de interesse (ROI). Estabelecemos metas claras para nossa ferramenta. Primeiro, queremos permitir que os desenvolvedores instrumentem partes de um programa com um tempo mínimo adicionado para Perfilamento contínuo ou descarregamento de código. Segundo, ela deve funcionar em vários tipos de dispositivos sem depender de recursos de hardware específicos. Por último, queremos garantir que ela possa medir cargas de trabalho multithreaded com precisão.

Nossa ferramenta reconhece ROIs e coleta dados de instruções antes do programa rodar para manter a sobrecarga de tempo baixa. Se contadores de desempenho estiverem presentes, ela pode pegar seus valores logo antes e depois de um ROI, permitindo comparações fáceis. Nossa ferramenta inclui um recurso básico de perfilamento que registra o tempo gasto em um ROI. Ela adiciona contadores que são atualizados em tempo de execução, o que, combinado com as informações coletadas durante a compilação, nos permite medir o uso da memória e a contagem de instruções para áreas específicas do código. Além disso, otimizamos nosso sistema para usar menos de um contador por bloco básico.

Construímos nossa ferramenta em LLVM, tornando-a facilmente portátil para muitos dispositivos. A maior parte do código está em um formato independente de arquitetura, e ela pode suportar execução multithreaded com contadores para cada thread. Focamos principalmente no uso da memória, mas nossa ferramenta também pode reunir mais dados sobre o desempenho das ROIs.

Avaliação e Resultados

Testamos nossa ferramenta em 24 aplicativos das suítes de benchmark GAPBS e SPEC2017. Nosso perfilamento resultou em um aumento médio no tempo de execução de apenas 8% em comparação com as versões não instrumentadas. Em comparação, usar uma ferramenta semelhante chamada pintool adicionou de 5 a 7 vezes o tempo de execução.

Comparamos as contagens de cargas e armazenamentos de memória com o que o pintool fornece e encontramos uma precisão de cerca de 93% para volumes de dados, com precisão de largura de banda em cerca de 87%. Também mostramos que nossa ferramenta pode funcionar bem em várias arquiteturas testando-a em sistemas AArch64, RISC-V e POWER8.

Contribuições

Este artigo apresenta um novo framework para checar o desempenho da memória que oferece informações detalhadas sobre regiões de interesse especificadas pelo usuário. Descrevemos uma maneira otimizada de coletar informações sobre tipos de instruções e uso da memória com baixa sobrecarga adicional. Também mostramos que a ferramenta é fácil de usar em novas arquiteturas, tendo funcionado em quatro sistemas diferentes. Por fim, projetamos nossa ferramenta para ser independente de hardware específico para dar suporte a uma variedade de aplicativos.

Estrutura do Framework

Nosso framework consiste em várias partes principais: uma passagem de IR LLVM, uma biblioteca de tempo de execução para gerenciar contadores, uma ferramenta de pós-processamento e uma biblioteca de comunicação para amostrar contadores em intervalos.

  1. Passagem de IR LLVM: Esta parte identifica o código dentro das ROIs e analisa os blocos básicos incluídos. O LLVM ajuda a organizar o grafo de controle de fluxo e destacar recursos chave, como contagens de loops e caminhos executados.

  2. Biblioteca de Tempo de Execução: Esta gerencia as leituras de contadores e garante medições corretas durante a execução. Ela adiciona instruções de temporização e lógica de controle para habilitar ou desabilitar contadores.

  3. Ferramenta de Pós-Processamento: Depois que o programa termina de rodar, esta ferramenta coleta todas as estatísticas e combina informações estáticas com medições dinâmicas.

  4. Biblioteca de Comunicação: Isso permite a amostragem periódica dos valores dos contadores sem esperar até que o programa termine, o que é útil para aplicativos de longa duração.

Medindo Desempenho

Para entender quão eficaz nossa ferramenta é, olhamos para várias métricas de desempenho:

  • Precisão dos Acessos à Memória: Queremos checar quantos bytes foram lidos ou escritos durante a execução. Os resultados mostraram uma precisão muito alta para as cargas de trabalho GAPBS, mas algumas cargas de trabalho SPEC tiveram alguns problemas, principalmente por causa de chamadas indiretas e funções de bibliotecas que não foram totalmente capturadas.

  • Largura de Banda da Memória: Analisamos o quão bem conseguimos avaliar o uso da largura de banda com base nos dados de acesso à memória que coletamos. Embora houvesse algumas variações, nossas medições capturaram as tendências gerais de forma adequada.

  • Sobrecarga de Tempo de Execução: Nossa ferramenta adiciona muito pouca sobrecarga em comparação com outras. Algumas cargas de trabalho até mantiveram tempos de execução semelhantes às versões não instrumentadas. No entanto, certas funções pesadas em controle de fluxo mostraram uma sobrecarga maior devido a interações mais complexas.

  • Eficiência de Amostragem: Checamos quão bem nosso método de amostragem funcionou comparando várias taxas de dados capturados. Na maior parte do tempo, nossa ferramenta fez um bom trabalho refletindo a carga de trabalho real, mas alguns cenários complicaram nossa análise.

Portabilidade

Outro objetivo importante era tornar nossa ferramenta portátil. Nós a adaptamos com sucesso para rodar em um servidor AArch64 e validamos sua funcionalidade em sistemas RISC-V e POWER8. A passagem IR é independente do hardware, o que ajuda a manter a consistência nas métricas entre diferentes arquiteturas. Garantimos que nossas medições se mantivessem confiáveis, mostrando padrões semelhantes independentemente do servidor usado.

Trabalhos Relacionados

Existem muitas ferramentas no passado para análise de desempenho, como gprof e Valgrind. Essas ferramentas costumam fornecer medições limitadas, seja apenas informações por chamada de função ou sofrendo com sobrecarga excessiva.

Também investigamos abordagens existentes, como PISA e sua versão mais nova, PISA-NMC, que oferecem informações sobre comportamentos no desempenho da memória, mas podem tornar os programas muito lentos. O DINAMITE tem suas próprias forças para identificar problemas de memória, mas também tem preocupações comparáveis de sobrecarga.

Conclusão

Resumindo, nosso trabalho apresenta uma nova ferramenta leve para checar o desempenho da memória, projetada especificamente para ajudar os desenvolvedores a entender melhor seus programas. Focando em partes específicas do código, nossa ferramenta pode fornecer insights valiosos enquanto mantém a sobrecarga baixa. À medida que continuamos a melhorar e adaptar nossa ferramenta em diferentes sistemas, esperamos ajudar os desenvolvedores a maximizar o desempenho da memória sem complicações desnecessárias.

No mundo da computação, onde velocidade e eficiência são fundamentais, cada pequeno aprimoramento conta, e esperamos que nossa ferramenta possa desempenhar um papel nessa busca!

Fonte original

Título: Examem: Low-Overhead Memory Instrumentation for Intelligent Memory Systems

Resumo: Memory performance is often the main bottleneck in modern computing systems. In recent years, researchers have attempted to scale the memory wall by leveraging new technology such as CXL, HBM, and in- and near-memory processing. Developers optimizing for such hardware need to understand how target applications perform to fully take advantage of these systems. Existing software and hardware performance introspection techniques are ill-suited for this purpose due to one or more of the following factors: coarse-grained measurement, inability to offer data needed to debug key issues, high runtime overhead, and hardware dependence. The heightened integration between compute and memory in many proposed systems offers an opportunity to extend compiler support for this purpose. We have developed Examem, a memory performance introspection framework based on the LLVM compiler infrastructure. Examem supports developer annotated regions in code, allowing for targeted instrumentation of kernels. Examem supports hardware performance counters when available, in addition to software instrumentation. It statically records information about the instruction mix of the code and adds dynamic instrumentation to produce estimated memory bandwidth for an instrumented region at runtime. This combined approach keeps runtime overhead low while remaining accurate, with a geomean overhead under 10% and a geomean byte accuracy of 93%. Finally, our instrumentation is performed using an LLVM IR pass, which is target agnostic, and we have applied it to four ISAs.

Autores: Ashwin Poduval, Hayden Coffey, Michael Swift

Última atualização: 2024-11-16 00:00:00

Idioma: English

Fonte URL: https://arxiv.org/abs/2411.12583

Fonte PDF: https://arxiv.org/pdf/2411.12583

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.

Artigos semelhantes