Memory und Leistungs-Optimierung
🔗Memory Anforderungen
Die Bearbeitung eines RAW Bildes in darktable braucht sehr viel Speicher. Eine ganz einfache Rechnung kann das zeigen: Für eine 20 Megapixel-Bild braucht darktable eine 4x32-bit Fliesskomma-Zelle, um jedes Pixel zu speichern, was bedeutet, jedes ganze Bild dieser Grösse wird deshalb ca 300 MB Speicher erfordern, um die Bilddaten zu speichern. Um dieses Bild nun tatsächlich in einem bestimmten Modul zu bearbeiten, braucht darktable zwei Pufferspeicher dieser Grösse (für die Eingabe und für die Ausgabe). Wenn wir ein komplexeres Modul haben, werden dessen Algorithmen zusätzlich mehrere zusätzliche Speicher für Zwischendaten erfordern. Ohne zusätzliche Optimierung, werden so irgendetwas zwischen 600MB und 3 GB von Speicher werden nötig sein, nur um die Bilddaten zu speichern und die Bilddaten zu bearbeiten. Darüber hinaus haben wir noch darktables Code Segment, den Code und die Daten aller dynamisch verbundenen Libraries, und auch zusätzlicher Puffer, dort wo darktable Bilder für einen schnellen Zugriff während dem Interaktiven arbeiten, zwischenspeichert (cache) für einen schnellen Zugriff beim interaktiven Arbeiten..
Zusammen erfordert darktable mindestens 4GB physikalisches RAM plus 8GB zusätzlichen Speicher für die Auslagerung, aber es wird besser laufen, je mehr Speicher du hast.
Wie auch mit der Ausführung in der CPU, haben viele Module von darktable Implementationen von OpenCL, um die Vorteile von parallelen Verarbeitungen deiner Grafikkarte (GPU) mitzunehmen. Ähnlcih auch ier, je mehr GPU Speicher du hast, umso besser wird darktable laufen.
🔗Kacheln
Wenn darktable nicht genügend Speicher für die Bearbeitung eines ganzen Bildes in einem Durchgang hat, dann werden die Module eine “Kachel-Strategie” wählen, in der das Bild in kleinere Teile (Kacheln) aufgeteilt wird, welche dann unabhängig bearbeitet und am Ende wieder zusammengefügt werden. Während diese Art zwar die Bearbeitung von Bildern mit einem viel kleineren Speicher ermöglicht, gibt es auch Nachteile:
-
Kacheln ist immer langsamer – oft bis zu 10x langsamer, obwohl für gewisse Module der Unterschied vernachlässigbar ist,
-
Kacheln ist für gewisse Module technisch wegen der nötigen Algorithmen nicht möglich
Für die meisten Systeme wird Kacheln vermutlich nur für den Export von Bildern voller Grösse nötig sein, mit effizienteren interaktiven Prozessen in der Dunkelkammer. Für die beste Performance (und um Kacheln zu verhindern), solltest du darktable mit möglichst wenigen andern Applikationen parallel laufen lassen und darktable dahingehend konfigurieren, so viel des GPU Memory zu nutzen wie möglich.
🔗Abstimmung der Performance
Es gibt eine Anzahl von Konfigurationsparametern, die helfen, die Performance des Systems fein abzustimmen. Gewisse dieser Parameter sind zu finden in darktable Voreinstellungen > Bearbeiten > CPU/GPU/Speicher, aber andere müssen direkt in der Konfigurationsdatei von darktable (zu finden in $HOME/.config/darktable/darktablerc
) modifiziert werden.
Dieser Abschnitt gibt dafür einige Leitlinien, wie man diese Einstellungen anpassen kann.
🔗Wie Testen
Um herauszufinden, um wie viel deine Anpassungen die Leistung von darktable erhöhen (oder nicht), brauchst du für das Testen eines oder mehrere Beispiel-Bilder und eine Methode zur Beurteilung der Geschwindigkeit der Pixelpipe,
Für Beispiel-Bilder empfiehlt es sich intensivere Module, wie zum Beispiel Diffusion Schärfe oder Entrauschen Profi. Exporte werden zwischen Pipe-Runs wohl mehr konsistente und vergleichbare Zeiten ergeben im Vergleich zu interaktiv arbeiten, sie werden aber auch die Hardware mehr fordern.
Um Informationen über das Profilieren zu erhalten, musst du darktable vom Terminal neu starten mit darktable -d opencl -d perf
. Falls du mehr Informationen über Kacheln solltest du darktable -d opencl -d tiling -d perf
nutzen.
Jedes Mal, wenn die Pixelpipe im Prozess ist (wenn du Modul-Parameter änderst, zoomen, schwenken, exportieren etc.) in der Session des Terminals wirst du die benötigte Gesamtzeit in der Pixelpipe und die benötigte Zeit in jedem der Open CL Kernels. Der zuverlässigste Wert ist die benötigte Zeit in der Pixelpipe und du solltest das für die Bewertung heranziehen.
Beachte: Die Zeitmessungen für jedes einzelne Modul sind unzuverlässig, wenn die Pixelpipe der OpenCL asynchron laufen (siehe den asynchronen Modus unten).
Um eine effiziente Bearbeitung mit OpenCL zu gewährleisten, ist es essentiell, dass wir die GPU am Laufen gehalten wird. Jegliche Unterbrechung oder stockender Datenfluss verlängert die Verarbeitungszeit. Dies ist besonders wichtig für die kleinen Bildpuffer, die während dem interaktiven Arbeiten gebraucht werden, welche einer schnellen GPU verarbeitet werden können. Selbst ein kurzzeitiges Stocken der Pixelpipe kann leicht zu einem Flaschenhals werden.
Auf der anderen Seite wird die Performance von darktable während des Dateiexports mehr oder weniger ausschliesslich von der Schnelligkeit der Algorithmen und den Pferdestärken deiner Grafikkarte bestimmt. Kurze Unterbrechungen werden keine merkliche Auswirkung auf die Dauer des Exports haben.
🔗Andere Ressourcen von darktable
Die “Ressourcen von darktable” Einstellung (in darktable Voreinstellungen > Bearbeitung > CPU/GPU/Speicher) erlaubt es dir zwischen vier unterschiedlichen Herangehensweisen die Ressourcen an darktable zuzuweisen. Jede dieser Optionen kontrolliert viele individuelle Parameter, die jeder für sich definiert sind, in $HOME/.config/darktable/darktablerc
. Du kannst jeden davon in deiner darktablerc Datei, um Werte für deinen Level von Ressourcen zu optimieren, obwohl du auch deinen Ressourcen-Level aus der Dropdown Liste hinzufügen kannst.
Jede der vier “Ressourcen von darktable”-Optionen werden wie folgt definiert:
Ressource_Standard=512 8 128 700
Ressource_gross=700 16 128 900
Ressource_klein=128 4 64 400
Ressource_unbeschränkt=16384 1024 128 900
Allgemeiner können dies auch vorgestellt werden als Ressource_level=a b c d
worin a
- d
wie folgt definiert werden:
- a. Systemspeicher für die Bearbeitung von Modulen
- der maximale Teil des Systemspeichers wird für die Bearbeitung von Modulen bereitgestellt. Kleiner Werte bewirken, dass speicherhungrige Module vermehrt mit Kacheln bearbeiten. Diese Zahl ist ein Teil des Gesamtwertes des System-Speichers geteilt durch 1024. Zum Beispiel in einem System mit 16 GB Systemspeicher, ist der Teil der als
Standard-Ressource
(in GB)16 * 512 / 1024
, oder 8GB von System RAM. - b. Minimale Puffergrösse zum Kacheln
- Die minimale Grösse eines Puffers zum Kacheln wird als Fraktion des gesamten Systemspeichers. Zum Beispiel wird bei einem System mit 16GB Systemspeichers ist die Höhe der zugewiesenen durch
Standard Ressource
(in GB) ist16 * 8 / 1024
, oder 0.125GB des System RAM. Beachte, dass diese Einstellung zur Hauptsache historisch und praktisch nicht mehr länger in Betrieb ist – es wird geraten, das beim Standard zu belassen. - c. Cache Memory für die Miniaturansichten
- Die Grösse des Memory für das Cache der Miniaturansichten. Auch das wird ausgedrückt als Bruchteil des System-Memory, und auf einem 16GB System ist die zugeteilte Grösse durch
Standard Ressource
ist16 * 128 / 1024
, oder 2GB des System RAM. - d. speicher für OpenCL
- Der maximale Anteil des GPU Memory, der für Bearbeitung mit Modulen zur Verfügung gestellt wird. Wie mit dem System Memory, bewirken niedrigere Werte, die Bearbeitung von speicher-hungrigen Modulen, vermehrt mit einer steigenden Zahl von Kacheln zu arbeiten. Deine GPU Memory wird wohl auch für andere Applikationen deines Systems genutzt werden. Jedoch kann deine GPU, im Gegensatz zum System Memory, nicht von einem Swap-Betrieb profitieren und es wird schwierig für darktable zu wissen, wie viel Speicher genau zu diesem Zeitpunkt zur Verfügung steht. Wenn der Wert zu hoch angesetzt wird, kann es sein, dass darktable auf eine CPU-Bearbeitung zurückfällt (die natürlich bedeutend langsamer ist). Deshalb beinhaltet der Anteil der GPU Memory einen Freiraum von 400MB Speicher, um eine zu hohe Zuteilung zu vermeiden. Zum Beispiel wird bei einer GPU von 6GB Memory darktable ungefähr
(6 - 0.4) * 700 / 1024
, oder 3.8GB vom GPU RAM beim Niveau derStandard Ressource
.
Zusätzlich zu den Anteilen der Ressourcen, die in der Benutzeroberfläche angezeigt werden, können noch die folgenden Optionen in der Befehlszeile gesetzt werden (z.B. darktable --conf resourcelevel="notebook"
). Diese Modi sind zur Fehlersuche bei Kacheln-Störungen da und bei der Test-Performance von gewöhnlichen Systemen auf grösseren Entwickler-Maschinen. Dabei gibt es die folgenden Optionen:
-
“mini” (1GB RAM, 2MB Einzel-Speicher, 128MB Miniaturanzeigen-Cache, 200MB OpenCL memory)
-
“notebook” (4GBRAM, 32MB Einzel-Speicher, 512MB Miniaturanzeigen-Cache, 1GB OpenCL memory)
-
“reference” (8GB RAM, 32MB Einzel-Speicher, 512MB Miniaturanzeigen Cache, 2GB OpenCL memory)
🔗Abstimmung des Gebrauches des GPU Memory
Wenn du mit OpenCL das Beste aus deinem GPU Memory herausholen willst, hast du drei Optionen:
-
Wähle den Ressourcenlevel “Gross”. Für eine 6GB Karte wird das ca. 5GB an GPU Memory beanspruchen, 1 GB bleibt für den Rest des Systems zur Verfügung.
-
Ändere darktablerc, um die letzte Zahl (den OpenCL Memory-Anteil) für deinen ausgewählten Level zu vergrössern. Zum Beispiel, ein Erhöhen des Anteils des OpenCL Memory auf 950 würde das zur Verfügung stehende Memory auf einer 6GB GPU auf ungefähr 5.3GB erhöhen.
-
Setze in darktable Voreinstellungen > Bearbeitung > CPU/GPU/Speicher > erhöhe OpenCL Performance auf “Memory-Grösse”, was dann das ganze Memory deines Gerätes, minus 400MB Freiraum. Siehe dazu den Abschnitt unten für zusätzliche Optionen zu diesen Einstellungen.
🔗Gerätespezifische Konfiguration von OpenCL
Die darktable Standardeinstellungen, sollten auf den meisten Systemen zu einer annehmbaren Grafikperformanz führen. Wenn du aber selber noch zusätzlich optimieren möchtest, zeigt dieser Abschnitt die Beschreibung der relevanten Konfigurationsparameter (welche alle in deiner darktablerc Datei gesetzt werden).
Seit darktable 4.0 werden die meisten Optionen im Zusammenhang mit OpenCL mit einer “pro Gerät”-Strategie gemanagt. Die Konfigurations-Parameter sehen für jedes Gerät so aus:
cldevice_v4_quadrortx4000=0 250 0 16 16 1024 0 0 0.017853
oder allgemeiner
cldevice_version_canonicalname=a b c d e f g h i
Ein Eintrag wird in darktablerc für jedes neu gefundene Gerät beim Start von darktable beim ersten Mal mit der korrekten Canonical-Gerätenummer und Versions-Nummer versehen. Die Parameter a
- i
werden wie folgt definiert und können manuell angepasst werden.
- a. avoid atomics
- 1 = vermeide atomics; 0 = nutze atomics
- Atomic Operationen sind in OpenCL eine spezielle Methode zur Datensynchronisierung und werden lediglich in wenigen Modulen verwendet. Leider sind einige alte AMD/ATI Karten extrem langsam bei der Verarbeitung von Atomics und für diese Karten ist es besser, die betroffenen Module auf der CPU arbeiten zu lassen, statt eine ultra-langsame GPU Verarbeitung hinzunehmen. Setze diesen Parameter auf 1, wenn du eine langsamme Verarbeitung von Modulen wie Schatten und Lichter, Monochrome, lokaler Kontrast, oder globales tonemapping (veraltet) sehr langsam arbeiten oder der Rechner zwischenzeitlich nicht mehr reagiert. Beachte, dass das Karten nach 2015 nicht beeinträchtigen sollte.
- b. micro nap
- Standard 250
- In einem Idealfall wirst du deine GPU 100 % am Laufen halten, wenn die Pixelpipe arbeitet. Wenn jedoch deine GPU auch für auch deinen Bildschirm updaten muss, und darktable nutzt sie zu 100%, kann es sein, dass nicht genügend Zeit für diese Aufgabe übrig bleibt. Normalerweise wird das eine ruckartige Reaktion deines GUI sein beim Schwenken, beim Zoomen oder wenn Schieber bewegt werden. Um das zu lösen, kann darktable kleine Unterbrechungen im Abarbeiten der Pixelpipe einschieben, damit die GPU etwas relaxen kann und GUI bezogenen Aktivitäten ausführen kann. Der Parameter “micro nap” kontrolliert die Dauer dieser Unterbrechungen in Mikrosekunden. Bei gegenwärtigen Systemen bist du mit dem Standard-Wert sehr gut dran, sogar bei integrierten Grafikkarten. Wenn du Vielfachgeräte nutzest oder du nutzest dein diskretes Gerät für zum Zeichnen auf deinem Bildschirm, kann der Wert für das nicht Desktop Gerät auf 0 gesetzt werden.
- c. gepinnter Speicher
- 0 = GUI verwenden, um den Modus auszuwählen; 1 = gepinnte Übertragung erzwingen; 2 = gepinnte Übertragung deaktivieren
- Beim Kacheln müssen riesige Speichermengen zwischen Host und Gerät übertragen werden. Bei manchen Geräten können direkte Speicherübertragungen zu und von einem beliebigen Host-Speicherbereich zu einer großen Leistungseinbuße führen. Dies macht sich besonders bemerkbar, wenn große Bilder auf kleinere Grafikkarten exportiert werden oder neuere Module wie Diffusion / Schärfen oder geführter Laplacian Modus in dem Spitzlicht Rekonstruktion Modul verwendet werden.
-
Es gibt keine sichere Methode oder allgemeine Regel, um vorherzusagen, ob dieser Parameter einen Leistungsvorteil bringt oder nicht, also müssen Sie selbst experimentieren. Dieser Modus kann auch global eingestellt werden, indem Sie die Option „Abstimmen der Leistung von OpenCL“ auf „Speichertransfer“ setzen (in [darktable-Voreinstellungen > Bearbeitung > CPU/GPU/Speicher](../preferences-settings/processing.md#cpu–gpu –memory)), in diesem Fall sollte dieser Parameter auf 0 gesetzt werden. Andernfalls können Sie ihn mit diesem Parameter auf Geräteebene aktivieren/deaktivieren.
- d. clroundup wh / e. clroundup ht
- Diese Parameter sollten auf diesem Standardwert belassen werden – Tests haben keinen Vorteil gezeigt, andere Werte zu verwenden.
- f. Anzahl der Event-Handles
- Event-Handles werden von darktable verwendet, um den Erfolg/Fehler von Kernels zu überwachen und Profilinformationen bereitzustellen, selbst wenn die Pixelpipe asynchron ausgeführt wird. Die Anzahl der Event-Handles ist eine begrenzte Ressource Ihres OpenCL-Treibers – obwohl sie recycelt werden können, gibt es eine begrenzte Anzahl, die gleichzeitig verwendet werden kann. Leider gibt es keine Möglichkeit, die Ressourcengrenzen für ein bestimmtes Gerät herauszufinden, daher verwendet darktable standardmäßig eine sehr konservative Schätzung von 128. Auf den meisten aktuellen Geräten und Treibern können Sie davon ausgehen, dass eine Zahl von bis zu 1024 sicher ist und zu einer etwas besseren OpenCL-Leistung führt. Wenn Ihrem Treiber die freien Handles ausgehen, treten fehlgeschlagene OpenCL-Kernel mit der Fehlermeldung „CL_OUT_OF_RESOURCES“ oder sogar Abstürze oder Systemeinfrierungen auf.
-
Ein Wert von 0 verhindert, dass darktable Event-Handles verwendet. Dies verhindert, dass darktable den Erfolg Ihrer OpenCL-Kernel ordnungsgemäß überwacht, spart jedoch etwas Treiber-Overhead, was zu einer besseren Leistung führt. Die Folge ist, dass alle Fehler wahrscheinlich zu einer verstümmelten Ausgabe führen, ohne dass darktable es bemerkt. Dies wird nur empfohlen, wenn Sie sicher sind, dass Ihr System felsenfest läuft.
- g. asynchroner Modus
- 1 = asynchronen Modus verwenden; 0 = nicht verwenden
- Dieses Flag steuert, wie oft darktable die OpenCL-Pixelpipe blockiert, um einen Status über Erfolg/Fehler der ausgeführten Kernel zu erhalten. Setzen Sie dies für eine optimale Latenz auf 1, damit darktable die Pixelpipe asynchron ausführt und versucht, so wenig Interrupts/Events wie möglich zu verwenden. Wenn OpenCL-Fehler wie fehlerhafte Kernel auftreten, setzen Sie den Parameter auf 0 (Standardeinstellung) zurück. Dies führt dazu, dass darktable nach jedem Modul unterbrochen wird, sodass Sie Probleme leichter eingrenzen können. Es wurden Probleme mit einigen älteren AMD/ATI-Karten (wie der HD57xx) gemeldet, die eine verstümmelte Ausgabe erzeugen können, wenn dieser Parameter auf 1 gesetzt ist. Belassen Sie im Zweifelsfall den Standardwert 0.
- h. Gerät deaktivieren
- 0 = Gerät aktivieren; 1 = Gerät deaktivieren
- Wenn darktable ein fehlerhaftes Gerät erkennt, wird es automatisch als solches markiert, indem dieser Parameter auf 1 gesetzt wird. Wenn Sie ein Gerät haben, das viele Fehler meldet, können Sie es manuell deaktivieren, indem Sie dieses Feld auf 1 setzen
- i. Benchmark
- Wenn darktable ein neues Gerät auf dem System erkennt, führt es einen kleinen Benchmark durch und speichert das Ergebnis hier. Sie können diesen Wert auf 0 zurücksetzen, um darktable zu zwingen, den Benchmark erneut durchzuführen, aber in den meisten Fällen sollten Sie diese Einstellung nicht ändern.
Note: Wenn darktable einen “fehlerhaften” Gerätekonfigurationsschlüssel entdeckt, wird er auf die Standardwerte zurückgeschrieben.
🔗id-spezifische OpenCL-Konfiguration
Ein zweiter gerätespezifischer Konfigurationsschlüssel wird ebenfalls bereitgestellt, der sowohl den Gerätenamen als auch die Geräte-ID berücksichtigt (nur für den Fall, dass Sie zwei identische Geräte haben). In diesem Fall _idX
folgt auf den üblichen Schlüsselnamen cldevice_version_canonicalname
, wobei X die Geräte-ID ist. Wenn beispielsweise das obige Beispielgerät als Gerät 0 bezeichnet wurde, wäre die zweite Konfigurationseinstellung (standardmäßig) cldevice_v4_quadrortx4000_id0=400
.
Für diesen Konfigurationsschlüssel ist derzeit nur ein einziger Parameter definiert:
- erzwungener Headroom (Standard 400)
- Die Speichermenge (in MB), die von darktable während der OpenCL-Verarbeitung nicht verwendet wird. Diese Einstellung ist nur gültig, wenn Sie preferences > processing > tune OpenCL performance auf “memory size” setzen.
-
Wenn Sie diesen Parameter auf Null (
0
) setzen, wird darktable beim ersten Durchlauf einer Pixelpipe versuchen, festzustellen, wie viel GPU-Speicher tatsächlich verfügbar ist, und verwenden diesen (mit einer Sicherheitsspanne von 100 MB) als die maximale Speichermenge, die darktable für den Rest seiner Sitzung verwendet. Dies ist normalerweise sicher, es sei denn, Sie starten andere Anwendungen (die eine Menge an GPU-Speicher verwenden), während darktable ausgeführt wird. Andernfalls könnte die Verwendung dieser Option Out-of-Memory Fehler verursachen, die dazu führen, dass darktable auf die CPU zurückgreift und die Leistung erheblich verringert. Sie können diese Option aus- und wieder einschalten, um darktable zu veranlassen, seine Speicherberechnung erneut durchzuführen (zu Beginn des nächsten Pipe-Runs). Beachten Sie, dass es bekannte Probleme mit der automatischen Speichererkennung bei neueren Nvidia-Treibern gibt, daher sollte die automatische Erkennung mit Vorsicht verwendet werden und ist daher standardmäßig deaktiviert. -
Wenn Sie sicher sind, dass keine Apps (oder Ihr Betriebssystem) das spezifische Gerät verwenden, können Sie diesen Parameter für das ansonsten nicht verwendete Gerät auf 1 setzen, damit darktable den gesamten Speicher dieses Geräts verwendet.
-
Der Standardwert von 400 MB sollte für die meisten Systeme ausreichend sein. Wenn Sie feststellen, dass Leistungsprobleme auftreten, weil darktable auf CPU zurückfällt, versuchen Sie, es auf 600 zu ändern oder “auf Speichergröße abstimmen” zu deaktivieren.
🔗andere Konfigurationsschlüssel
Die folgenden zusätzlichen Konfigurationsschlüssel sind auch in darktablerc verfügbar:
- cldevice_version_canonicalname_building
- Diese Option wird beim Kompilieren von OpenCL-Kernels verwendet und kann zur Leistungsoptimierung oder zur Umgehung von Fehlern bereitgestellt werden. Sie müssen alle vorhandenen Kernel entfernen, um sie mit den neuen Optionen neu zu kompilieren. Geben Sie eine leere Zeichenfolge an, um Kernel ohne Optionen neu zu kompilieren. Entfernen Sie die Einstellung vollständig, um Kernel mit den Standardoptionen neu zu kompilieren. Der aktuelle Standardwert ist
-cl-fast-relaxed-math
. - opencl_synch_cache
- Wenn dieser Parameter auf „true“ gesetzt ist, zwingt er darktable, Bildpuffer von Ihrer GPU nach jedem Modul abzurufen und sie in seinem Pixelpipe-Cache zu speichern. Dies ist ein ressourcenintensiver Vorgang, kann aber je nach GPU sinnvoll sein (auch wenn die GPU eher langsam ist). In diesem Fall kann darktable tatsächlich etwas Zeit sparen, wenn sich Modulparameter geändert haben, da es zu einem zwischengespeicherten Zwischenzustand zurückkehren und nur einen Teil der Pixelpipe erneut verarbeiten kann. In vielen Fällen sollte dieser Parameter auf “active module” (Standardeinstellung) eingestellt werden, wodurch nur die Eingabe des aktuell fokussierten Moduls zwischengespeichert wird.