7.0 KiB
Projektbericht – Tricorn-Fraktal
1. Ziel des Projekts
Ziel ist ein C-Programm, welches einen Ausschnitt des Tricorn-Fraktals berechnet und als BMP-Datei abspeichert. Über Kommandozeilenargumente werden Startpunkt, Bildgröße, Auflösung, maximale Iterationszahl, Ausgabedatei, Farbmodus und Implementierungsvariante festgelegt. Neben der skalaren Vergleichsversion enthält das Projekt SIMD- und Thread-Varianten, deren Laufzeiten miteinander verglichen werden.
2. Implementierungen
V1 ist die skalare Vergleichsimplementierung. Real- und Imaginärteil werden direkt mit float-Operationen berechnet. Das Bild wird zeilenweise durchlaufen und die Koordinaten werden inkrementell erhöht.
V2 verarbeitet vier benachbarte Pixel gleichzeitig mit 128-Bit-SSE-Registern. Eine aktive Maske speichert, welche SIMD-Lanes die Fluchtschranke noch nicht überschritten haben. Sobald alle vier Lanes inaktiv sind, wird die Iterationsschleife beendet. Für null bis drei Restpixel am Zeilenende wird eine skalare Funktion verwendet.
V0, die Hauptimplementierung, verwendet ebenfalls SIMD. Gegenüber V2 werden Real- und Imaginärkoordinaten inkrementell als Vektoren fortgeführt.
V3 erweitert die optimierte SIMD-Berechnung um POSIX-Threads. Die verfügbaren logischen Prozessoren werden mit sysconf beziehungsweise GetSystemInfo bestimmt. Jeder Thread erhält einen zusammenhängenden Zeilenbereich und schreibt ausschließlich in diesen Teil des gemeinsamen Bildpuffers. Bei kleinen Bildern wird die Threadzahl reduziert, sodass ungefähr mindestens zehn Zeilen pro Thread verbleiben.
3. Tests und Performanzanalyse
Die Laufzeit wird mit clock_gettime(CLOCK_MONOTONIC) gemessen. Im Benchmark-Modus wird die gewählte Berechnung mehrfach ausgeführt; die BMP-Ausgabe liegt außerhalb der Messung. Der Mittelwert ist Gesamtzeit geteilt durch Wiederholungszahl. Der Speedup gegenüber einer Referenz (R) lautet
S=\frac{T_R}{T_\mathrm{optimiert}}
Die Testsuite enthält ein farbiges 1920×1080-Bild, ein 7680×4320-Bild mit niedriger Iterationszahl, einen vergrößerten Fraktalrand und einen nahezu schwarzen Bereich mit hoher Iterationszahl. Für einen fairen Versionsvergleich müssen in jedem Szenario identische Parameter verwendet werden
Wir haben versucht die Tests so zu wählen, dass unsere Implementierungen in den verschiedenen Situationen auch zu merklich unterschiedlichen Ergebnissen kommen. Dies führt zu einer hohen Ausagekraft über die Stärken und Schwächen.
Alle Tests wurden auf der Rechnerhalle ausgeführt, um das Potential unserer Optimierungen auf High-End Hardware zu ergründen.
Testumgebung:
- Host-System: TUM lxhalle
- OS: Ubuntu 24.04.2 LTS
- CPU: AMD EPYC 9554P 64-Core Processor
- Thread-Anzahl: 64 physische Kerne / 128 logische Threads
- Taktfrequenz: Basis 2.3 GHz / Boost 3.1 GHz
- L3 Cache: 256 MiB
- L2 Cache: 64 MiB
- RAM: 768 GB
- Compiler: gcc 13.3.0 (mit -O3 flag)
(Diese Spezifikationen werden aus der Ausgabe von lscpu und lshw Befehle auf lxhalle, der CIT wiki und der Message of the Day)
Alle Benchmarking-Tests wurden 100 mal ausgeführt um genaue Messwerte zu erhalten.
Test 1: Default 1920x1080 Bild
| Durchnitliches Laufzeit | Speedup gegenüber V1 | |
|---|---|---|
| V0 | 0.046 | 3.2528 |
| V1 | 0.150 | 1.00 |
| V2 | 0.047 | 3.21 |
| V3 | 0.007 | 20.29 |
Test 2: 7680×4320-Bild mit niedriger Iterationszahl
| Durchnitliches Laufzeit | Speedup gegenüber V1 | |
|---|---|---|
| V0 | 0.047 | 1.81 |
| V1 | 0.086 | 1.00 |
| V2 | 0.049 | 1.74 |
| V3 | 0.006 | 13.71 |
Test 3: Fraktalrand
| Durchnitliches Laufzeit | Speedup gegenüber V0 | |
|---|---|---|
| V0 | 0.591 | 2.54 |
| V1 | 1.502 | 1.00 |
| V2 | 0.419 | 3.59 |
| V3 | 0.031 | 48.38 |
Test 4: Schwarzen Bereich mit hoher Iterationszahl
| Durchnitliches Laufzeit | Speedup gegenüber V0 | |
|---|---|---|
| V0 | 1.572 | 3.55 |
| V1 | 5.589 | 1.00 |
| V2 | 1.573 | 3.55 |
| V3 | 0.022 | 250.64 |
4. Korrektheit und Fazit
Zur Korrektheitsprüfung wurden V0, V1, V2 und V3 mit identischen Parametern ausgeführt. Die erzeugten Graustufenbilder wurden mit ImageMagick und der Metrik AE pixelweise verglichen. Von insgesamt 523776 Pixeln unterschieden sich V0 und V1 an 5864 Pixeln (1,120 %), V2 und V1 an 5523 Pixeln (1,054 %) sowie V3 und V1 an 5993 Pixeln (1,144 %).
Die Implementierungen erzeugen somit keine vollständig identischen Ergebnisse. Ursache sind unterschiedlich angeordnete Gleitkommaoperationen bei der Berechnung der komplexen Koordinaten. Da res nicht immer exakt als float darstellbar ist, entstehen kleine Rundungsabweichungen, die insbesondere nahe der Fraktalgrenze eine andere Fluchtiteration verursachen können.
Zusätzlich wurden nicht durch vier teilbare Bildbreiten, positive und negative Höhen sowie Grau- und Farbausgabe getestet. Die verbleibenden Pixel am Zeilenende wurden durch den skalaren Restpfad verarbeitet. Bei umgekehrter Bildhöhe traten ebenfalls geringe Rundungsabweichungen auf.
Die Messungen zeigen, dass SIMD die skalare Berechnung deutlich übertrifft. V3 erreicht gegenüber V1 einen Speedup zwischen 13,71 und 250,64. Der größte Vorteil tritt bei hohen Iterationszahlen auf, da der Aufwand für die Thread-Verwaltung gegenüber der eigentlichen Berechnung weniger ins Gewicht fällt. V0 und V2 besitzen dagegen in mehreren Tests nahezu identische Laufzeiten, sodass die Thread-Parallelisierung den größten zusätzlichen Performanzgewinn liefert.
Insgesamt zeigt das Projekt die schrittweise Optimierung von einer skalaren Implementierung über SIMD bis zur Kombination aus SIMD und Multithreading. Grenzen bleiben Rundungsabweichungen, unterschiedlich lange aktive SIMD-Lanes, der Aufwand der Thread-Verwaltung und die Geschwindigkeit von RAM-Zugriffen.
5. Individuelle Beiträge
Yashar Alan Zenker:
- Konzeptionierung der grundlegenden Algorithmusstruktur
- SISD und Threading Implementationen
- Integration von SIMD und Threading
- Cleanups und Refactoring
Nikola Granitsky:
- Implementierung von SIMD- und Skalar-Optimierungen
- Implementierung des BMP-Exports
- Konzeption und Integration von Testfällen
- Refactoring und Bugfixing
Cem Temizkan:
- Implementierung des Rahmenprogramms
- Implementierung der Kommandozeilenverarbeitung
- Implementierung des Benchmarkings
- Beschreibung der mathematischen Grundlagen.