Temos um problema desagradável de desempenho ao executar nosso software de renderização multithread dentro de uma máquina virtual.
Estamos executando o Kubuntu 12.04 em um VirtualBox 4.0.10_Debianr72436 que roda sem cabeça no servidor de computação Debian (6.0.6, 2.6.32-5-amd64). Possui processador Intel Xeon X5660 de 2 * 6 núcleos com hyperthreading e cerca de 64 GB de memória operacional. Nós nos conectamos à VM por meio do TigerVNC Viewer para X versão 1.1.0. A máquina virtual está atualmente configurada para usar todos os 24 núcleos, mas os problemas descritos abaixo podem ser observados quando ela é configurada para contagens mais baixas (por exemplo, 12).
O problema:
Quando executamos nosso renderizador com apenas um thread de renderização, ele roda em velocidade comparável à que obtemos quando rodamos diretamente em metal em outras máquinas (Intel Core 2 Duo MacBooks). No entanto, à medida que aumentamos o número de threads de trabalho, ele acelera apenas ligeiramente (bem longe de 1/n) e em torno de 5 threads ele começa a desacelerar. A partir de 8 threads é ainda mais lento que um aplicativo de thread único. Quando o renderizador é executado diretamente no metal em nossos MacBooks, não há problemas, não importa quantos threads você especifique para executar. Por exemplo, 16 threads em uma CPU dual core são executados tão rápido quanto a instância de dois threads.
Em seguida, tentamos executar várias instâncias de thread único de nosso renderizador em paralelo, com resultados surpreendentes. Quando executamos 4 instâncias, está tudo bem - elas rodam na mesma velocidade de uma instância, mas quando executamos 6 instâncias, todas elas ficam lentas em cerca de 50%!
Também tentamos executar outro renderizador (pbrt v.2) para testar como os outros estão se saindo e se seus resultados foram melhores. Ele escalou bem para 13 threads, mas também ficou mais lento (mas não tanto quanto nosso software).
Nosso renderizador é escrito em Objective C combinado com C e bits de assembler. Usamos operações XADD e CAS em nosso código para acessar dados compartilhados. Há uma forte suspeita de que estes dois possam ser a origem dos nossos problemas. Alguma idéia sobre isso?
A propósito: não podemos instalar o tempo de execução Obj-C e outras bibliotecas necessárias e executar nosso software diretamente no metal devido à política do servidor.
Trecho de configuração da VM:
- Tamanho da memória: 4000 MB
- Fusão de páginas: desativado
- Tamanho da VRAM: 12 MB
- HPET: desligado
- Chipset: piix3
- Firmware: BIOS
- Número de CPUs: 24
- CPU Sintética: desligada
- Substituições de CPUID: Nenhuma
- ACPI: ativado
- IOÁPICO: ativado
- PAE: desligado
- Deslocamento de tempo: 0 ms
- RTC: UTC
- Hardw. virt.ext: ativado
- Hardw. virt.ext exclusivo: desativado
- Paginação aninhada: ativada
- Páginas grandes: ativadas
- VT-x VPID: ativado
- Aceleração 3D: desligada
- Aceleração de vídeo 2D: desativada
- Nível de execução de adições: 2
- Tamanho do balão de memória configurado: 0 MB
Responder1
Estou cuspindo aqui, mas... Na GUI, clique com o botão direito na instância do Kubuntu e escolha as configurações enquanto ela não estiver em execução. Verifique se sua CPU está limitada lá. Você provavelmente desejará ver como o seu sistema responde à escolha de 20 ou 22 CPUs em vez de 24 para mitigar a competição de recursos entre a caixa virtual e a caixa host. Em seguida, tente executar uma única instância com 20 threads. Eu esperaria ver o pico da CPU na máquina para os 20 núcleos e os 4 restantes também aumentariam para 100% enquanto tentava acompanhar. Você tem outros aplicativos em execução nesta máquina além da sua VM?