Nesta postagem, vou apresentar o que considero a fundamentação teórica básica sobre os supercomputadores modernos utilizados para computação de alto desempenho. Não irei me aprofundar em todos os detalhes, mas é um texto com informações suficientes para quem não é da área e deseja ter uma noção básica do funcionamento dessas máquinas. Ao final do texto, espero que o leitor tenha entendimento da arquitetura do hardware e do ambiente de software fornecido pelo gerenciador de recursos.
As plataformas de computação paralela evoluíram de forma radical no decorrer dos anos. A partir dos supercomputadores vetoriais da década de 1970, passando pelos MPPs (Massive Parallel Processors) (Massive Parallel Processors) na década de 1980 até o Cluster Beowulf nos anos 90, temos nos dias de hoje uma arquitetura híbrida baseada em clusters com nós de processamento com processadores de vários núcleos e aceleradores. Um supercomputador moderno é uma evolução dos primeiros clusters. Em outras palavras, arquiteturas baseadas em clusters são predominantes, mas alguns elementos dos supercomputadores clássicos ainda persistem. Apresentamos aqui as principais características de um supercomputador moderno. Baseamos nossa descrição nos sistemas descritos na lista TOP500 e na máquina instalada no CENAPAD-UFC.
A menor parte de um supercomputador moderno que executa uma imagem do sistema operacional é chamada de nó de processamento. A figura abaixo é uma representação em alto nível da arquitetura interna. Nessa figura, podemos observar dois processadores (CPU0 e CPU1). Essa quantidade de chips pode variar. Cada processador tem acesso ao banco de memória, que apesar de aparecer como duas entidades separadas na imagem, trata-se de um espaço de endereçamento global. Além disso, dentro de cada processador existem vários núcleos (cores) que compartilham memória cache (oculta na ilustração para efeito de simplificação). Os processadores podem se comunicar entre si através de um protocolo proprietário.
Os processadores se comunicam com outros periféricos através de barramentos PCI Express (alto desempenho), PCI apenas ou SATA. No caso dos dois últimos barramentos, a comunicação é feita por intermédio de um chip especializado para controlar E/S (Ponte E/S). A comunicação entre a ponte e as CPUs é feita por acesso direto à memória. Os aceleradores são componentes dedicados capazes de executar certos cálculos com melhor desempenho do que CPUs tradicionais. Existe toda uma área de estudo dedicada a aceleradores, mas não vou me aprofundar aqui. Ao mais interessados, sugiro uma busca por NVIDIA CUDA no Google ;).
Para otimizar a execução de aplicações paralelas que fazem uso de troca de mensagens, a configuração de rede em um cluster para computação de alto desempenho pode apresentar duas redes (interfaces NIC0 e NIC1), com tecnologias diferentes. A rede de gerência utiliza tecnologia ethernet e é usada para login remoto e sistemas de arquivos distribuídos. Ela não tem nenhuma diferença em relação a redes locais tradicionais, exceto que costuma utilizar a última versão do padrão ethernet (atualmente, 100-Gigabit_Ethernet) e utiliza comutadores (switches) de qualidade superior. O padrão ethernet só determina os protocolos de acesso ao enlace. Os outros protocolos necessários para comunicação (IP para rede e TCP/UDP para transporte) são implementados por software no kernel do sistema operacional. A camada de software entre a aplicação e o enlace não é motivo de preocupação para as aplicações tradicionais. Porém, para aplicações de computação de alto desempenho, o software implica uma latência que é prejudicial ao desempenho dessas aplicações. Em busca de diminuir a latência, a rede de computação utiliza protocolos que minimizam a presença de software na pilha, tentando implementar o máximo possível em hardware. Um exemplo é a tecnologia Infiniband, na qual até a camada de transporte a comunicação é tratada diretamente pelo adaptador. Dessa forma, mais do que a largura de banda, a latência é otimizada, requisito crucial para o desempenho de aplicações de computação de alto desempenho. A desvantagem é que o adaptador se torna mais complexo, aumentando o custo de implantação de redes Infiniband
A figura abaixo apresenta a organização de rede do cluster do CENAPAD-UFC. Nesse projeto, os nós de processamentos são construídos em blades, que são agrupados em chassis, gabinetes com comutadores ethernet e infiniband embutidos. Além dos nós que executam a computação em si, temos um nó de gerência que serve como porta de entrada para o cluster. É nesse nó que os usuários realizam login e configuram as submissões para o sistema.
Cada chassi possui comutadores para as duas tecnologias (infiniband e ethernet), mas como um chassi suporta ao máximo 16 blades, mais dois switches infiniband e um switch ethernet são necessários para conectar os chassis e completar os 48 blades do cluster. É possível observar porque o custo da Infiniband é maior. As duas redes são conectadas à um nó de gerência, no qual os jobs dos usuários são submetidos. Importante notar que o sistema de storage é ligado apenas na rede de gerência, na qual é acessado através de sistema de arquivos distribuído. Um nó do cluster possui uma imagem própria do sistema operacional. O sistemas operacionais mais utilizados são aqueles derivados do UNIX. Até o final da década de 1990, era comum que cada fabricante tivesse sua versão própria do UNIX. Com a popularização do Linux, os fabricantes encontraram um sistema UNIX robusto de baixo custo capaz de substituir as soluções proprietárias. O custo de manutenção do Linux é dividido por uma comunidade de vários desenvolvedores autônomos e empresas. Para os fabricantes de supercomputadores, resta desenvolver apenas drivers específicos e otimizações do kernel para sua máquinas. O kernel do Linux por si próprio não é o suficiente para um sistema funcional. Distribuições são coleções de aplicativos que formam um sistema completo para o usuário final. As distribuições Linux para supercomputadores apresentam customizações para executar aplicações de alto desempenho, mas são baseadas em distribuições já existentes no mercado. O Red Hat Enterprise Linux e o SUSE são escolhas populares.
Sistemas gerenciadores de recursos permitem que vários usuários utilizem um supercomputador com menor esforço administrativo e diminuição da ociosidade. Através de um sistema de filas, usuários submetem aplicações como tarefas no nó de gerência. Além de ponto de submissão, o nó de gerência também controla o acesso ao sistema de arquivos distribuído instalado no storage. Na listagem abaixo, temos um exemplo de um arquivo definição de tarefa baseado no SLURM (Simple Linux Utility for Resource Management). Nesse arquivo, o usuário dá um nome a tarefa (CALCULO_PI), define a quantidade de nós processamentos utilizados (4) e quantos processos são criados (48). Neste caso específico, são criados 12 processos em cada nó de processamento. O tempo máximo de execução da tarefa é determinado (1 hora). Por último, uma linha definindo o binário a ser executado é informada (./pi).
#!/bin/bash
#SBATCH -J CALCULO_PI
#SBATCH --partition particao_0
#SBATCH --nodes 4
#SBATCH --ntasks 48
#SBATCH --time 1:00:00
srun --resv-ports ./pi
Ao ser submetido no nó de gerência, a tarefa entra numa fila inicial que analisa para qual partição ela está destinada. O conceito de partição corresponde a um subconjunto dos recursos do cluster. Essa divisão auxilia a definir prioridades. Por exemplo, um partição pode ser destinada apenas aos pesquisadores sênior de um instituição, incluindo todos os recursos disponíveis. Uma outra partição menor pode incluir apenas os recursos menos poderosos, destinada aos alunos de graduação. A listagem a seguir apresenta os parâmetros para definição de uma partição chamada partição_0 no SLURM. Observa-se que além que configurar quais usuários têm acesso e quais nós de processamento fazem parte da partição, um limite máximo para o tempo de execução das aplicações é informado.
PartitionName=particao_0
Nodes=Processamento_[0-3]
Default=NO
MaxTime=240:00:00
AllowGroups=ufc,ufrgs,uespi,utfpr,ufpb,ufsc,ufma,ufpe,ufal
State=UP
A próxima figura apresenta um exemplo do sistema de filas em gerenciador de recursos. O usuário submete tarefas para um partição escolhida, de acordo com seus privilégios. O sistema encaminha a tarefa para a fila adequada, na qual aguarda a execução. Uma vez que existem recursos livres, a tarefa é executada. O usuário não precisa monitorar todo o processo. O gerenciador de recursos se responsabiliza por todos os passos entre a submissão e a conclusão da execução.
Apesar de controlar vários blades distintos, o gerenciador de recursos atua dentro de um mesmo domínio administrativo. O cluster é um sistema distribuído controlado. O acesso externo só é permitido ao nó de gerência, sendo que várias restrições de firewall são utilizadas para proteger o supercomputador de acesso indevido. Para permitir a utilização de clusters de instituições diferentes, outras tecnologias de computação distribuída mais amplas são necessárias, fornecendo controle de autorização e autenticação, além de um serviço de transferência de dados de alto desempenho.