NumaRing: Topology-Aware Routing for NUMA-Local MPMC Queues, and What Broke When We Optimized It
Este artigo apresenta o NumaRing, uma implementação de fila MPMC ciente de topologia que demonstra como descobertas baseadas em perfilamento — especificamente a eliminação de uma custosa busca de topologia por operação, a correção de um gargalo de átomo compartilhado em work-stealing e a remoção de um backoff de CPU-pause ineficaz — podem melhorar drasticamente o desempenho, ao mesmo tempo em que revelam que, mesmo com essas otimizações, o throughput bruto em um sistema de dois sockets permanece muito abaixo dos alvos de design originais.
Artigo original sob licença CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Esta é uma explicação gerada por IA do artigo abaixo. Não foi escrita nem endossada pelos autores. Para precisão técnica, consulte o artigo original. Ler aviso legal completo
Os computadores modernos são construídos como cidades movimentadas com múltiplos distritos, cada um abrigando seu próprio poder de processamento e memória. Quando um programa precisa realizar um trabalho, ele envia uma solicitação para um distrito específico. Se os dados de que ele precisa já estiverem na memória local desse distrito, a tarefa acontece instantaneamente. Mas se a solicitação tiver que viajar para um distrito diferente para buscar informações, a jornada leva significativamente mais tempo. Esse atraso, causado pela distância física entre os distritos, é um limite fundamental de como essas máquinas são construídas. Por décadas, engenheiros de software tentaram escrever programas que mantenham os dados e os trabalhadores que os utilizam no mesmo distrito, esperando evitar as lentas viagens intermunicipais. O desafio é que, quando muitos trabalhadores tentam acessar uma lista de tarefas compartilhada ao mesmo tempo, os congestionamentos que eles criam podem ser tão prejudiciais quanto a própria distância.
Um pesquisador decidiu construir uma maneira melhor de gerenciar essas listas compartilhadas, especificamente para computadores com dois distritos distintos. Ele criou um sistema chamado NumaRing, projetado para manter os trabalhadores e seus dados locais ao seu próprio distrito sempre que possível. A ideia era simples: se um trabalhador estiver no primeiro distrito, ele deve olhar apenas para a lista no primeiro distrito. Se essa lista ficar cheia ou vazia, o sistema moveria um lote de tarefas para o outro distrito de uma só vez, em vez de mover as tarefas uma por uma. Essa abordagem prometia manter o tráfego local rápido enquanto minimizava as viagens lentas de longa distância. No entanto, quando o pesquisador colocou seu sistema à prova, descobriu que suas melhores intenções continham armadilhas ocultas. Ao medir o sistema com extrema precisão em vez de apenas supor como ele funcionava, ele descobriu que dois erros específicos estavam retardando o sistema mais do que o próprio hardware, e que um conselho comum para corrigir lentidões de computador estava, na verdade, piorando as coisas.
O pesquisador começou construindo seu sistema em um computador na nuvem com dois distritos, cada um contendo dezesseis processadores virtuais. Ele o preencheu com um fluxo constante de tarefas, observando quanto tempo levava para uma tarefa ir do início da linha até o fim. No início, o sistema foi surpreendentemente lento. O pesquisador percebeu que toda vez que um trabalhador tentava adicionar ou remover uma tarefa, o software fazia uma pergunta: "Em qual distrito estou agora?". Essa pergunta parecia inofensiva, mas a resposta demorava muito para ser computada. O software estava recalculando a localização do zero a cada vez, mesmo que a localização do trabalhador raramente mudasse. Esse cálculo repetido era como um motorista parando em cada interseção para pedir direções, mesmo sabendo exatamente para onde estava indo. O custo dessa pergunta era tão alto que consumia mais de onze vezes o esforço da tarefa real de mover os dados.
Assim que o pesquisador corrigiu isso, lembrando a localização e verificando-a apenas quando necessário, o sistema acelerou dramaticamente. O número de tarefas processadas por segundo saltou de seis a sete vezes mais. Mas a história não terminou aí. Quando adicionaram mais trabalhadores à máquina, o sistema encontrou um novo obstáculo. Os trabalhadores ainda esperavam demais, especialmente quando o sistema estava sob forte pressão. Investigando mais a fundo, descobriram um segundo problema na forma como os trabalhadores compartilhavam tarefas entre os distritos. Quando um trabalhador precisava pegar um lote de tarefas de outro distrito, cada trabalhador estava lutando pelo mesmo contador pequeno para decidir quem seria o próximo. Isso criou um enorme congestionamento no portão. Ao dar a cada trabalhador seu próprio contador privado para usar, o pesquisador removeu esse gargalo. Essa mudança foi ainda mais dramática, reduzindo o tempo que um trabalhador tinha que esperar no meio da linha em mais de duzentos vezes.
Com essas duas grandes correções em vigor, o pesquisador esperava que seu sistema fosse um campeão. Ele havia eliminado os erros de software que o estavam atrasando. No entanto, quando levou a máquina ao seu limite absoluto com trinta e dois trabalhadores, o sistema ainda não conseguia atingir a velocidade que originalmente esperava. O pesquisador então testou uma técnica padrão usada para resolver lentidões de computador chamada "backoff" (recuo). A ideia por trás do backoff é que, se um trabalhador falhar ao tentar pegar uma tarefa, ele deve esperar um momento antes de tentar novamente, esperando que a fila diminua. Em muitas situações, essa pausa ajuda. Mas neste cenário específico de alta pressão, a pausa foi um erro. O pesquisador mediu que esperar na verdade custou quinze a trinta por cento de sua velocidade total. O caminho mais rápido era continuar tentando imediatamente, porque o hardware já estava lidando com o conflito de forma eficiente o suficiente para que esperar apenas desperdiçasse tempo.
O quadro final que emergiu foi de tanto sucesso quanto de limites rígidos. O pesquisador construiu com sucesso um sistema que mantinha os dados locais e corrigiu dois grandes bugs de software que causavam atrasos massivos. Ele provou que uma estratégia de otimização comum pode ser prejudicial em certos cenários de alta velocidade. No entanto, apesar dessas vitórias, o sistema ainda não conseguia processar tarefas tão rápido quanto o objetivo de design original. O pesquisador concluiu que o atraso restante não era um erro de software que ele pudesse corrigir, mas um limite físico da própria máquina. A distância entre os dois distritos e a largura de banda da estrada que os conectava criaram um teto que nenhum código inteligente poderia romper com esse design. Ele relatou suas descobertas honestamente, mostrando exatamente onde seu sistema teve sucesso, onde falhou e por que o próprio hardware foi o juiz final. Seu trabalho serve como um lembrete de que, no mundo da computação de alta velocidade, entender a máquina física é tão importante quanto escrever o código.
Afogado em artigos na sua área?
Receba digests diários dos artigos mais recentes que correspondam às suas palavras-chave de pesquisa — com resumos técnicos, no seu idioma.