Otimizando o Desempenho
Nesta seção:
Antes de submeter jobs para processamento definitivo, é fundamental realizar estudos de otimização. O objetivo é encontrar o equilíbrio ideal entre recursos solicitados, tempo de espera na fila e tempo de execução.
Por Que Otimizar?
Verificar se a instalação do software foi bem-sucedida
Descobrir os recursos mínimos necessários para boa performance
Aumentar a prioridade solicitando apenas o necessário
Reduzir o tempo de espera na fila
Obter resultados mais rápido com uso eficiente de recursos
Fatores a Considerar
Fator |
Impacto |
|---|---|
Número de CPUs |
Mais CPUs podem acelerar, mas nem sempre linearmente |
Memória disponível |
Afeta capacidade de processamento e evita swapping |
Número de nós |
Distribuir entre nós pode introduzir latência de comunicação |
Tempo solicitado |
Jobs mais curtos têm prioridade maior |
Local de I/O (Leitura/Escrita) dos dados |
|
Exemplo Prático de Otimização
Vamos acompanhar o usuário Spock otimizando seu programa “dobra_4.py”.
Cenário: Programa processa arquivos de entrada e produz resultados. Spock quer encontrar a configuração ideal.
Teste 1: 24 processos em 12 nós (1 CPU por processo)
#!/bin/bash
#SBATCH -t 24:00:00
#SBATCH -n 24
#SBATCH -N 12
#SBATCH -c 1
export INPUT="energia.in combustivel.in dobra_4.py"
export OUTPUT="light-speed.data"
module load intel/compilers
module load anaconda3
source activate startrek
job-nanny srun python dobra_4.py --input=energia.in,combustivel.in
Resultados:
Tempo de execução: 13h55min
Espera na fila: 10h
Tempo total até resultado: 23h55min
Importante
O comando srun é uma ferramenta usada no Slurm Workload Manager (um agendador de tarefas comumente usado em computadores de alto desempenho e supercomputadores). Ele é usado para solicitar recursos computacionais (como CPUs, GPUs e memória) e executar tarefas paralelas nesses recursos.
Teste 2: 24 processos em 8 nós (1 CPU por processo)
#!/bin/bash
#SBATCH -t 24:00:00
#SBATCH -n 24
#SBATCH -N 8
#SBATCH -c 1
Resultados:
Tempo de execução: 11h15min
Espera na fila: 6h
Tempo total até resultado: 17h15min ✓ Melhor até agora
Teste 3: 24 processos em 12 nós (2 CPUs por processo)
#!/bin/bash
#SBATCH -t 24:00:00
#SBATCH -n 24
#SBATCH -N 12
#SBATCH -c 2 # 2 CPUs por processo = 48 CPUs totais
Resultados:
Tempo de execução: 6h30min (mais rápido!)
Espera na fila: 25h (muito mais espera)
Tempo total até resultado: 31h30min
Teste 4: 24 processos em 1 nó (2 CPUs por processo)
#!/bin/bash
#SBATCH -t 24:00:00
#SBATCH -n 24
#SBATCH -N 1
#SBATCH -c 2 # 2 CPUs por processo = 48 CPUs totais
Resultados:
Tempo de execução: 3h (excelente!)
Espera na fila: 72h (muito longa)
Tempo total até resultado: 75h
Tabela Comparativa
Teste |
Processos |
Nós |
CPUs/Proc |
Total CPUs |
Espera |
Execução |
Tempo total |
|---|---|---|---|---|---|---|---|
1 |
24 |
12 |
1 |
24 |
10:00 |
13:55 |
23:55 |
2 |
24 |
8 |
1 |
24 |
06:00 |
11:15 |
17:15 |
3 |
24 |
12 |
2 |
48 |
25:00 |
06:30 |
31:30 |
4 |
24 |
1 |
2 |
48 |
72:00 |
03:00 |
75:00 |
Conclusão de Spock: O Teste 2 oferece o melhor equilíbrio entre espera e execução (17h15min totais).
Estratégias de Otimização
Comece com recursos mínimos
# Teste inicial com poucos recursos #SBATCH -n 1 #SBATCH -t 01:00:00 #SBATCH --mem=2G
Aumente gradualmente
# Próximo teste #SBATCH -n 4 #SBATCH -t 02:00:00 #SBATCH --mem=8G
Monitore o uso real
# Após o job terminar sacct -j JOBID --format=JobID,MaxRSS,Elapsed,CPUTime
Ajuste baseado nos dados
Se MaxRSS é muito menor que a memória solicitada, reduza a memória
Se Elapsed é muito menor que a tempo solicitado, reduza o tempo
Se CPU time é muito maior que Elapsed, há paralelização ineficiente
HTC: “Quebrando” Grandes Inputs (HTC)
O GridUnesp pode ser usado de duas formas:
HPC (High Performance Computing): Muitas threads para um único job
HTC (High Throughput Computing): Muitos jobs pequenos processando partes de um grande problema
Exemplo de HTC:
Em vez de 1 job processando um arquivo de 10 GB:
# Único job grande
./processar dados_completos_10GB.dat
você pode dividir em 100 jobs processando arquivos de 100 MB cada:
#!/bin/bash
#SBATCH --array=1-100
#SBATCH -n 1
#SBATCH -t 01:00:00
#SBATCH --mem=2G
export INPUT="dados_parte_${SLURM_ARRAY_TASK_ID}.dat"
export OUTPUT="resultado_parte_${SLURM_ARRAY_TASK_ID}.dat"
job-nanny ./processar $INPUT > $OUTPUT
Vantagens do HTC:
Cada job pequeno começa mais rápido
Melhor aproveitamento de recursos ociosos
Menor impacto de falhas (apenas poucos sub-jobs são perdidos)
Escalabilidade quase linear
Trade-offs entre /tmp/ e /store/
Configuração |
Local de I/O |
Velocidade |
Quando usar |
|---|---|---|---|
1 nó, sem flags |
|
⚡⚡⚡ Muito rápida |
I/O intensivo, dados <100GB |
1 nó, |
|
⚡ Média |
Dados >100GB, 1 nó |
Múltiplos nós |
|
⚡ Média |
Jobs MPI, dados compartilhados |
Recomendação:
Sempre que possível, use 1 nó e /tmp/ para I/O intensivo
Para dados muito grandes (>100GB), use
export LARGE_FILES="true"no script de submissãoPara jobs MPI, aceite a latência do /store/ em troca da escalabilidade
Checklist de Otimização
Antes de submeter seu job definitivo:
[__] Testei com uma amostra pequena dos dados
[__] Monitorei o uso real com
sacct[__] Ajustei memória para o valor real (com margem de segurança)
[__] Ajustei tempo para o valor real (com margem de segurança)
[__] Escolhi o número ideal de CPUs/processos
[__] Decidi entre 1 nó (/tmp/) ou múltiplos nós (/store/)
[__] Considerei dividir em Job Array (HTC)
[__] Verifiquei o Fair Share do meu grupo (Política de Prioridade)
Ver também
Política de Prioridade - Como a prioridade afeta seus jobs
Memória Compartilhada - OpenMP e threads
Memória Distribuída - MPI e processos distribuídos
Job Array - Múltiplos jobs para HTC
Guia Completo de Armazenamento - Detalhes sobre /tmp/ e /store/