Revisão de artigo para disciplina Arquitetura de Computadores Artigo: NDS: N-Dimensional Storage Aluno: Marco A. B. Montevechi Filho Na transferência de grandes segmentos de dados n-dimensionais para aceleradores de hardware, um gargalo do processo de salvamento em storage é a serialização dos dados em segmentos lineares de memória. O artigo apresenta o N-Dimensional Storage (NDS) como uma solução que abstrai o acesso à memória de maneira a otimizá-lo. Os fatos de que as estruturas de dados ótimas para determinados tipos de processamento mudam de aplicação para aplicação, de que a lógica de acesso à memória por uma aplicação não necessariamente reflete a lógica de acesso à memória pelo hardware, e de que a otimização de dados para storage pode ser diferente da otimização para processamento são apontados como desafios para um modelo genérico de otimização. Neste contexto, NDS permite que as aplicações sejam consumidoras ou fornecedoras de espaços de dimensões customizadas na memória, que podem ser abstraídos através de um Space Translation Layer (STL). Ou seja, os blocos fundamentais de memória para uma aplicação são organizados de maneira a otimizar a banda de acesso em hardware e a minimizar o overhead de processamento envolvido na serialização dos dados. Para um caso particular de multiplicação de matrizes de (32K)2 elementos em um sistema com CPU AMD RyZen 3700X e uma GPU Nvidia RTX 2080, o artigo chega a explicitar que o tempo de overhead de conversão em CPU do formato serial de memória para o formato matricial utilizado pelo kernel chega a ser quase 4 vezes maior que o próprio tempo de processamento do kernel. Assim, são traçados os seguintes requisitos para uma organização de estrutura de dados que otimize tanto o processamento em kernels de aceleradores quanto o acesso à memória: - Diminuir o overhead de processamento em conversão de dimensionalidades; - Permitir à aplicação utilizar ao máximo a banda de acesso à memória; - Minimizar o número de comandos de I/O enviados ao sistema. A tríade de desafios: “diferentes arquiteturas de acesso à memória em hardware”, “diferentes tipos ótimos de dados para diferentes kernels” e “mismatch entre tipos de dados ótimos para processamento em kernel e para acesso à memória” é evidenciada de maneira minuciosa, mas desnecessariamente repetitiva. Para cumprir os três requisitos definidos acima, a camada de tradução utiliza três parâmetros para definir como estruturar os dados: um endereçamento de início, o volume da estrutura de dados e o número de dimensões de cada objeto. Estes parâmetros são utilizados para estruturar os dados em building blocks de tamanho mínimo determinado pela multiplicação do número máximo de pedidos paralelos possíveis de acesso ao storage pela granularidade mínima de um único acesso básico, fazendo com que um pedido de acesso na camada de tradução se transforme em tantos pedidos de acesso paralelos quantos possíveis. Assim, otimiza-se tanto o uso da banda de acesso ao hardware quanto o custo de conversões dimensionais. A busca por esses elementos na memória através da camada de tradução pode ser feita inclusive por uma aplicação que represente os dados em dimensões diferentes, desde que o tamanho total ocupado na memória seja o mesmo. A figura 1 (no artigo, figura 4) ilustra conceitualmente a tradução. Figura 1 - Camadas de tradução de dados n-dimensionais para storage. Embora NDS não seja completamente transparente à aplicação, necessitando de chamadas explícitas através de uma API, ele permite que um programador se preocupe apenas com a otimização da estrutura de dados para o kernel de processamento, abstraindo a otimização de acesso à memória. Além disso, o artigo sugere compatibilidade entre as chamadas de read/write e chamadas de API para movimentação de estruturas n-dimensionais, como cudaMemcpy2D. Apesar da boa formatação da solução e da qualidade na implementação, a prova de conceito - realizada em um AMD RyZen 3700X octa-core com SSD de 32 canais e uma GPU NVIDIA RTX 2080 - revela que overheads de memória e processamento gerados pela STL geram efeitos consideráveis, inclusive piorando a banda de acesso efetiva em alguns casos. De fato, a otimização de acesso à memória ocorre efetivamente apenas em casos específicos, a depender da formatação dos dados. Por um lado, é esperado que um sistema de aceleração seja eficiente apenas em casos específicos. Por outro, o artigo poderia tornar a piora na performance menos surpreendente se, ao início da discussão, propusesse menor grau de generalização no uso da solução. Além disso, o uso de um hardware mais customizado para implementação do sistema é apresentado como opcional a princípio, mas mostra-se quase essencial em vários casos. Novamente, algo esperado para um sistema de aceleração, mas que poderia ser melhor expresso no início. Em suma, NDS é uma ótima solução para um problema que certamente será mais recorrente conforme se populariza o uso de sistemas de aceleração mas, como frequentemente é o caso na computação heterogênea, não pode ser apresentado como uma solução completamente genérica.