Beim Ausführen unserer Multithread-Rendering-Software in einer virtuellen Maschine tritt ein unangenehmes Leistungsproblem auf.
Wir führen Kubuntu 12.04 in einer VirtualBox 4.0.10_Debianr72436 aus, die ohne Treiber auf einem Debian-Server (6.0.6, 2.6.32-5-amd64) läuft. Sie hat einen Intel Xeon X5660-Prozessor mit 2 x 6 Kernen und Hyperthreading sowie etwa 64 GB Arbeitsspeicher. Wir stellen über TigerVNC Viewer für X Version 1.1.0 eine Verbindung zur VM her. Die virtuelle Maschine ist derzeit so eingerichtet, dass sie alle 24 Kerne verwendet, aber die unten beschriebenen Probleme können auftreten, wenn sie auf eine geringere Anzahl (z. B. 12) konfiguriert wird.
Das Problem:
Wenn wir unseren Renderer mit nur einem Rendering-Thread ausführen, läuft er mit einer Geschwindigkeit, die mit der vergleichbar ist, die wir erreichen, wenn wir ihn direkt auf Metal auf anderen Maschinen (Intel Core 2 Duo MacBooks) ausführen. Wenn wir jedoch die Anzahl der Arbeitsthreads erhöhen, wird er nur geringfügig schneller (ziemlich weit von 1/n entfernt) und bei etwa 5 Threads beginnt er tatsächlich langsamer zu werden. Ab 8 Threads und mehr ist er sogar langsamer als eine Single-Thread-Anwendung. Wenn der Renderer direkt auf Metal auf unseren MacBooks ausgeführt wird, gibt es keine Probleme, egal wie viele Threads Sie zum Ausführen angeben. Beispielsweise laufen 16 Threads auf einer Dual-Core-CPU so schnell wie die Instanz mit zwei Threads.
Wir haben dann versucht, mehrere Single-Thread-Instanzen unseres Renderers parallel laufen zu lassen, mit überraschendem Ergebnis. Wenn wir 4 Instanzen laufen lassen, ist alles in Ordnung – sie laufen mit ähnlicher Geschwindigkeit wie eine Instanz, aber wenn wir 6 Instanzen laufen lassen, werden alle um etwa 50 % langsamer!
Wir haben auch versucht, einen anderen Renderer (pbrt v.2) auszuführen, um zu testen, wie andere abschneiden und ob ihre Ergebnisse besser sind. Er ließ sich gut auf bis zu 13 Threads skalieren, wurde dann aber ebenfalls langsamer (aber nicht so sehr wie unsere Software).
Unser Renderer ist in Objective C geschrieben, kombiniert mit C und Assembler-Teilen. Wir verwenden in unserem Code XADD- und CAS-Operationen für den Zugriff auf gemeinsam genutzte Daten. Es besteht der starke Verdacht, dass diese beiden die Ursache unserer Probleme sein könnten. Irgendwelche Ideen dazu?
Übrigens: Aufgrund der Serverrichtlinien können wir die Obj-C-Runtime und andere benötigte Bibliotheken nicht installieren und unsere Software nicht direkt auf dem Metal ausführen.
VM-Konfigurationsauszug:
- Speichergröße: 4000 MB
- Seitenfusion: aus
- VRAM-Größe: 12 MB
- HPET: aus
- Chipsatz: piix3
- Firmware: BIOS
- Anzahl der CPUs: 24
- Synthetische CPU: aus
- CPUID-Überschreibungen: Keine
- ACPI: ein
- IOAPIC: ein
- PAE: aus
- Zeitversatz: 0 ms
- Echtzeituhr: UTC
- Hardw.virt.ext: ein
- Hardw. virt.ext exklusiv: aus
- Verschachtelte Paging: ein
- Große Seiten: ein
- VT-x VPID: ein
- 3D-Beschleunigung: aus
- 2D-Videobeschleunigung: aus
- Ergänzungen Laufebene: 2
- Konfigurierte Speicher-Balloon-Größe: 0 MB
Antwort1
Ich sage nur, was ich meine, aber ... Klicken Sie in der GUI mit der rechten Maustaste auf die Kubuntu-Instanz und wählen Sie „Einstellungen“, während sie nicht ausgeführt wird. Prüfen Sie, ob Ihre CPU dort begrenzt ist. Sie möchten wahrscheinlich sehen, wie Ihr System auf die Auswahl von 20 oder 22 CPUs anstelle von 24 reagiert, um den Ressourcenwettbewerb zwischen virtueller und Host-Box zu mildern. Versuchen Sie dann, eine einzelne Instanz mit 20 Threads auszuführen. Ich würde erwarten, dass die CPU-Auslastung auf der Maschine für die 20 Kerne ansteigt und die verbleibenden 4 ebenfalls auf 100 % steigen, während sie versuchen, mitzuhalten. Laufen auf dieser Maschine außer Ihrer VM noch andere Anwendungen?