Skip to content

Otimizações

Aviso

As otimizações destacadas a seguir podem não ser aplicáveis a sistemas com diferentes sistemas operacionais, versões de kernel, ou hardwares, e tampouco para propósitos distintos dos abordados neste guia. Em outros cenários, elas podem até impactar negativamente o desempenho.

BIOS

Aqui serão destacadas otimizações que devem ser feitas na BIOS da máquina, os termos e caminhos até chegar a opção podem variar de sistema para sistema ou de bios para bios.

Os tunings abaixo foram testados e validados para os servidores Supermicro 1029U-E1CRTP2 com processadores Intel Xeon Gold 5118 2.3GHz.

Categoria Item Caminho Config. Padrão Config. Performance
CPU Hyper Threading Advanced -> CPU Configuration -> Hyper Threading Enabled Disabled
CPU Aumentar frequência de operação dos cores Advanced -> CPU configuration -> Advanced power management configuration -> Power technology Energy Efficient Custom
CPU Aumentar frequência de operação dos cores Advanced -> CPU configuration -> Advanced power management configuration -> Power performance tuning OS control EPB BIOS control EPB
CPU Aumentar frequência de operação dos cores Advanced -> CPU configuration -> Advanced power management configuration -> Energy_perf_Bias_cfg_mode Disabled Balanced performance
CPU Suporta a virtualização Advanced -> CPU configuration -> Intel virtualization technology Enable Disable
RAM Aumentar a frequência de operação das memórias Advanced -> Chipset configuration -> North bridge -> memory configuration -> memory frequency Auto 2933Mhz

Gravação do video de demonstração de configuração: https://eduplay.rnp.br/portal/video/tunebios100g

Nele são explicados um pouco dos conceitos por trás de cada tuning. Adicionalmente foi mostrado outros tunings testados, mas que não tiveram efeito na performance.

Sistema Operacional

Plano de energia do CPU e clock fixo

  • O que faz:

    A frequência do CPU pode ser ajustada dinamicamente pelo sistema para economizar energia, mas em ambientes de rede de alta performance, isso pode introduzir latência ao aumentar o tempo de resposta do CPU. O comando cpupower fixa a frequência do CPU em 2.3GHz em todos os núcleos e muda o "governador" para o modo performance, que força o CPU a manter uma frequência alta, evitando o "throttling" (diminuição do clock) que poderia ocorrer no modo de economia de energia.

  • Impacto:

    Com a frequência da CPU constante e o modo performance ativado, a latência do sistema diminui e o tempo de resposta melhora, particularmente importante para processar pacotes de rede rapidamente.

  • Comando(s) de ajuste:

    cpupower -c all frequency-set -f 2.3GHz
    cpupower frequency-set -g performance
    

Ajustar tamanho do MTU

  • O que faz:

    Esse comando define o MTU (Maximum Transmission Unit) da placa de rede para 9000 bytes, permitindo o uso de jumbo frames. Jumbo frames são pacotes de rede maiores que o padrão de 1500 bytes.

  • Impacto:

    Com um MTU maior, a rede pode transferir mais dados por pacote, reduzindo a sobrecarga de processamento causada pela fragmentação. Essa otimização é particularmente útil em redes de alta velocidade e grande volume de dados, pois diminui a latência e aumenta a eficiência no transporte de grandes quantidades de informação. No entanto, é importante que todos os dispositivos ao longo do caminho suportem jumbo frames; caso contrário, pode haver fragmentação desnecessária ou perda de pacotes.

  • Comando(s) de ajuste:

    ip link set <NIC_NAME> mtu 9000
    
    ### EXEMPLO:
    # ip link set eth0 mtu 9000
    

Ajustar tamanho dos buffers TCP

  • O que faz:

    Esses comandos configuram o tamanho máximo dos buffers de recepção (rmem_max) e de envio (wmem_max) para o kernel, bem como o tamanho máximo do buffer opcional (optmem_max). As variáveis tcp_rmem e tcp_wmem definem os tamanhos mínimo, padrão e máximo dos buffers de recepção e envio específicos do protocolo TCP, respectivamente. Esses valores aumentam a capacidade dos buffers de recepção e envio para valores máximos, permitindo que o TCP gerencie grandes quantidades de dados sem ficar limitado pela capacidade de buffer padrão.

  • Impacto:

    Maximização do uso da largura de banda disponível por meio da redução de congestionamentos e retransmissões. O aumento dos buffers permite ampliar a janela de envio e recepção (cwnd) em conexões de alta latência, garantindo um throughput mais consistente ao possibilitar que o TCP mantenha o envio eficiente de dados.

  • Comando(s) de ajuste:

    Para definir o tamanho ideal dos buffers TCP, é fundamental calcular o Bandwidth Delay Product (BDP), que nos dá o tamanho ideal do buffer para maximizar a eficiência de redes de alta largura de banda e latência. O BDP é calculado multiplicando a largura de banda pela latência, e o resultado representa o tamanho ideal de buffer para transmissão e recepção.

    A fórmula para calcular o BDP é:

    \[ \text{BDP} = \text{Bandwidth} \times \text{Round-Trip Time (RTT)} \]
    • Bandwidth: A largura de banda da conexão, expressa em bits por segundo (bps).
    • RTT (Round-Trip Time): A latência da rede em segundos (tipicamente em milissegundos, ms).

    Para obter o BDP em bytes, divida o resultado por 8 (convertendo bits para bytes).

    Imagine uma rede com largura de banda de 100 Gbps e um RTT de 100 ms:

    1. Converta a largura de banda para bps:

      \[ 100 \, \text{Gbps} = 100 \times 10^9 \, \text{bps} \]
    2. Converta a RTT para segundos:

      \[ 100 \, \text{ms} = 0,1 \, \text{s} \]
      \[    \text{BDP} = 100 \times 10^9 \, \text{bps} \times 0,1 \, \text{s} = 10 \times 10^9 \, \text{bits} \]
    3. Converta para bytes:

      \[    \text{BDP} = \frac{10 \times 10^9}{8} = 1,25 \times 10^9 \, \text{bytes} \, (1,25 \, \text{GB}) \]

    Assim, o buffer TCP ideal seria em torno de 1,25 GB para atender à capacidade de transmissão.

    sysctl -w net.core.rmem_max=<BDP em bytes>
    sysctl -w net.core.wmem_max=<BDP em bytes>
    sysctl -w net.ipv4.tcp_rmem='4096 <valor intermediário> <BDP em bytes>'
    sysctl -w net.ipv4.tcp_wmem='4096 <valor intermediário> <BDP em bytes>'
    
    ### Exemplo:
    # sysctl -w net.core.rmem_max=1342177280  # 1.25 GB
    # sysctl -w net.core.wmem_max=1342177280  # 1.25 GB
    # sysctl -w net.core.optmem_max=2147483647   # 1.25 GB
    # sysctl -w net.ipv4.tcp_rmem='4096 0000000000000 1342177280'   # '4MB 180MB 1.25GB'
    # sysctl -w net.ipv4.tcp_wmem='4096 0000000000000 1342177280'   # '4MB 180MB 1.25GB'
    

Ring buffer e Interrupt coalescence

  • O que faz:
    • Ring Buffer: Aumentar o tamanho dos buffers de recepção (RX) e transmissão (TX) para o máximo (8192) permite que a placa de rede (NIC) armazene mais pacotes antes de precisar interromper o CPU para processá-los.
    • Interrupt Coalescence: O processo de interrupt coalescence (coalescência de interrupções) agrupa múltiplos eventos de interrupção em um só, reduzindo o workload do CPU ao processar pacotes recebido na placa de rede. ethtool -C com adaptive-rx e adaptive-tx ativa a adaptive coalescence (coalescência adaptativa), ajustando dinamicamente a taxa de interrupções com base no workload sob a placa de rede.
  • Impacto:
    • Ring Buffer: Buffers maiores são cruciais em ambientes de alta taxa de pacotes, como 100/200/400 Gbps, onde a placa de rede pode processar muitos pacotes rapidamente. Buffers pequenos podem causar "packet drops" (perda de pacotes).
    • Interrupt Coalescence: A coalescência de interrupções reduz a sobrecarga na CPU, consolidando várias interrupções em uma só, permitindo que o sistema processe pacotes de forma mais eficiente em altas velocidades.
  • Comando(s) de ajuste:

    ethtool -G <NIC_NAME> rx 8192 tx 8192
    ethtool -C <NIC_NAME> adaptive-rx on adaptive-tx on
    
    ### EXEMPLO:
    # ethtool -G eth0 rx 8192 tx 8192
    # ethtool -C eth0 adaptive-rx on adaptive-tx on
    

Fair Queueing (FQ)

  • O que faz:

    Os sistemas Linux usam um algoritmo de controle de filas chamado qdisc (Queueing Discipline) para gerenciar como os pacotes são enfileirados e transmitidos. A fila padrão (pfifo_fast) não oferece um controle justo em redes congestionadas. O fq (Fair Queueing) distribui a largura de banda de maneira mais justa entre múltiplos fluxos TCP, evitando que um fluxo monopolize o canal de dados.

  • Impacto:

    O uso de fq melhora a justiça na distribuição de pacotes em situações de alta carga, prevenindo que certos fluxos TCP obtenham tratamento preferencial. Em redes de alta performance, como 100 Gbps, isso garante que múltiplos fluxos de dados possam coexistir sem degradação significativa do desempenho.

  • Comando(s) de ajuste:

    sysctl -w net.core.default_qdisc=fq
    
  • Referências:


Habilitar o IOMMU

  • O que faz:

    O IOMMU (Input-Output Memory Management Unit) é uma tecnologia que mapeia endereços de dispositivos de I/O (input e output) diretamente para a memória física, permitindo que dispositivos como placas de rede acessem diretamente a memória sem intervenção contínua do CPU. Em servidores com placas de rede de alta velocidade, como 100 Gbps (ex.: Mellanox ConnectX), o IOMMU pode reduzir o overhead do sistema ao lidar com grandes volumes de dados.

  • Impacto:

    O uso de IOMMU melhora o throughput ao reduzir a latência associada à movimentação de dados entre dispositivos e a memória do sistema, resultando em melhor performance.

  • Comando(s) de ajuste:

    O suporte a IOMMU precisa ser configurado no GRUB do sistema.

    Aplique as seguintes alterações de acordo com a arquitetura da máquina (AMD ou Intel). Adicione estas linhas no arquivo /etc/default/grub .

    • Maquina Intel:

      GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"
      
    • Maquina AMD:

      GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt"
      

    Após adicionar a configuração, execute o seguinte comando para atualizar o GRUB:

    /usr/sbin/update-grub
    

    Reinicie o sistema, e confirme se a configuração foi aplicada corretamente, através do seguinte comando:

    cat /proc/cmdline
    

    O retorno deve ser algo semelhante a:

    root=/dev/mapper/vg0-root ro iommu=pt
    

Controle de fluxo (flow control)

  • O que faz:

    O controle de fluxo utiliza quadros de pausa (pause frames) para sinalizar a um dispositivo que ele deve parar temporariamente de enviar dados, ajudando a evitar a sobrecarga do receptor. Sem controle de fluxo, há risco de perda de pacotes quando o buffer do receptor está cheio, o que pode degradar o desempenho da rede em altas taxas de transmissão.

  • Impacto:

    Ativar o controle de fluxo garante que a transmissão de dados seja pausada quando o receptor estiver saturado, prevenindo perda de pacotes e retransmissões desnecessárias, que podem impactar seriamente a performance de redes de 100/200/400 Gbps.

  • Comando(s) de ajuste:

    ethtool -A <NIC_NAME> rx on tx on
    
    ### EXEMPLO:
    # ethtool -A eth0 rx on tx on
    

Desativar cache de ssthresh

  • O que faz:

    O TCP utiliza uma métrica chamada ssthresh (Slow Start Threshold) para controlar o crescimento da janela de congestão. Quando uma conexão TCP termina, o valor de ssthresh é salvo. Com tcp_no_metrics_save=1, o sistema evita reutilizar o valor de ssthresh de conexões anteriores, forçando uma negociação limpa a cada nova conexão.

  • Impacto:

    Esta alteração melhora a eficiência de novas conexões TCP, evitando que condições temporárias de congestionamento de conexões anteriores prejudiquem o desempenho de conexões subsequentes.

  • Comando(s) de ajuste:

    sysctl -w net.ipv4.tcp_no_metrics_save=1
    

Habilitar detecção de MTU

  • O que faz:

    O MTU (Maximum Transmission Unit) determina o tamanho máximo de um pacote de rede. Quando o MTU é maior que o permitido, os pacotes são fragmentados, o que pode diminuir o desempenho. O MTU probing (detecção de MTU) permite ao TCP descobrir dinamicamente o tamanho ideal de MTU ao longo de uma conexão, evitando fragmentação.

  • Impacto:

    Para redes de alta performance que utilizam jumbo frames (pacotes maiores que o padrão de 1500 bytes), a detecção de MTU ajusta dinamicamente o tamanho do pacote, evitando fragmentação e, consequentemente, melhorando o throughput.

  • Comando(s) de ajuste:

    sysctl -w net.ipv4.tcp_mtu_probing=1
    

CPU Affinity

Observação

Aplicável apenas a arquiteturas multi-numa

  • O que é uma arquitetura multi-NUMA:

    Em computadores convencionais, todos os núcleos do processador compartilham um barramento de memória único e uniforme, conectando-os a um controlador de memória centralizado. Isso caracteriza uma topologia UMA (Uniform Memory Access), pois a largura de banda e a latência de acesso à memória são homogêneas para todos os núcleos.

    Uma arquitetura multi-NUMA (Non-Uniform Memory Access) divide o sistema em múltiplos "nós" (nodes), cada um contendo um conjunto de núcleos de CPU e memória associada. A vantagem dessa configuração é que cada nó pode acessar sua própria memória com baixa latência. Contudo, o acesso à memória de outros nós pode ser mais lento, tornando crucial a otimização do sistema para que os recursos intensivos em dados, como a rede, permaneçam no mesmo nó para evitar latências adicionais.

  • Identificando em qual nó NUMA a NIC está conectada:

    Para saber a qual NUMA node a NIC está conectada, use o comando abaixo, que mostrará o número do node relacionado à NIC:

    cat /sys/class/net/<NIC_NAME>/device/numa_node
    
    ### Exemplo
    # cat /sys/class/net/eth0/device/numa_node
    

    Um valor numérico indicará o NUMA node associado, enquanto -1 indica que a NIC não está associada a um node específico.

  • Identificando os núcleos do CPU pertencentes ao NUMA:

    Para listar os núcleos de CPU associados a um NUMA específico, execute:

    lscpu | grep 'NUMA node'
    

    Este comando mostrará cada NUMA node seguido da lista de núcleos pertencentes a ele. Assim, você pode identificar quais núcleos usar na configuração de afinidade com a NIC.

  • O que faz:

    Em sistemas de alta performance, o daemon irqbalance distribui automaticamente as interrupções de hardware entre os núcleos. No entanto, isso nem sempre é ideal para arquiteturas multi-NUMA, onde uma distribuição eficiente é crítica. A configuração manual de afinidade de interrupções permite que as interrupções da NIC sejam processadas exclusivamente pelos núcleos de CPU no mesmo NUMA node, o que reduz a latência no acesso à memória.

  • Impacto:

    O ajuste manual da afinidade de interrupções é essencial para maximizar o desempenho. Isso garante que as interrupções da NIC sejam tratadas pelos núcleos de CPU mais próximos da interface de rede, o que reduz significativamente a latência de memória melhorando o throughput.

  • Comando(s) de ajuste:

    Script

    Esse script, fornecido pela Mellanox, é projetado para configurar e verificar a afinidade entre núcleos de CPU e a NIC. Embora voltado para NICs Mellanox, ele também pode ser usado com NICs de outros fabricantes.

    Link para download: mlnx_tuning_scripts.tar.gz

    Para configurar a afinidade por NUMA node, execute:

    systemctl stop irqbalance
    /opt/testbed_ps/mlnx_tuning_scripts/set_irq_affinity_bynode.sh <NODE_NUMBER> <NIC_NAME>
    
    ### EXEMPLO:
    # /opt/testbed_ps/mlnx_tuning_scripts/set_irq_affinity_bynode.sh 1 eth0
    

    Nesse exemplo, todas as interrupções da NIC eth0 serão processadas pelos núcleos do NUMA node 1, garantindo o processamento próximo à memória do mesmo node, o que minimiza latência e maximiza a performance de rede.