Technologie-Stack: C # / .NET 4 / WinForms
Hintergrund:
Das Projekt, an dem ich arbeite, ist eine Visualisierungsanwendung für eine Reihe von Bildstapeln. Insbesondere ist jeder Bildstapel zu einem Gitter ausgerichtet, zeigt das gleiche Bild zu jeder Zeit, und Verarbeitungsfunktionen werden auf die gegenwärtig angezeigten Bilder angewendet. Die Bildstapel selbst sind 150-300 MB und jedes Bild ist 512 KB-1 MB. Ein typischer Datensatz besteht aus ~ 100 Bildstapeln.
Frage:
Um zu versuchen, mit dieser Datenmenge zu arbeiten, verwende ich mehrere Techniken:
Aber selbst wenn man all das oben genannte verwendet, lässt die Reaktionsfähigkeit viel zu wünschen übrig. Bei Verwendung des Prozess-Explorers von SysInternals ist die CPU-Auslastung niedrig (& lt; 25%), während die Speicherbelegung den Grenzwert erreicht, bevor die Speicherbereinigung stattfindet.
Die Profilerstellung zeigt, dass die meiste Ausführungszeit dafür aufgewendet wird, Daten aus den im Speicher abgelegten Dateien abzurufen. Ich nehme an, es wartet, wie das Betriebssystem den angeforderten Speicher in den aktiven Speicher zurücksendet?
Was könnte ich noch tun, um die Leistung zu verbessern?
Hinweis:
Update 1:
Zunächst einmal ist es nicht sehr hilfreich, unsicheren Code und gespeicherte Dateien zu verwenden. Sie müssen rund 20 GB Daten von der Festplatte lesen. Das Lesen von der Festplatte dauert viel länger als eine zusätzliche Kopie im Speicher, wenn Sie nur Streams verwenden - Sie haben sie an der falschen Stelle optimiert.
Ich denke, du solltest es aus einem anderen Blickwinkel betrachten. Sie zeigen Stapel von Bildern mit einem Wert von 20 GB auf einem Bildschirm, der weniger als 10 MB Daten anzeigen kann. Sie müssen nicht 20 GB Daten lesen, um alle Bildstapel anzuzeigen und während der Verarbeitung dieser Bilder eine ansprechende Benutzeroberfläche bereitzustellen. Sie müssen nur das oberste Bild von jedem Stapel laden - das wird viel viel schneller sein.
Was die eigentliche Verarbeitung betrifft, so können Sie, sofern Sie die GPU nicht irgendwie verwenden können, nicht schneller vorgehen, als Bilder parallel zu verarbeiten. Ich denke, es hängt von der Verarbeitung ab, die du tatsächlich tust.
Sie können immer noch vorgenerierte Thumb-Bilder pro Bild erstellen und nur diese in Grid
laden, wenn alle Bilder verfügbar sind. In dem Moment, in dem der Benutzer einen Effekt / eine Transformation auf das Bild anwendet, können Sie nur dieses Bild laden. Und auch bei der Beladung von nur das Bild, das Sie es zu Clipping-Sektoren Laden devide können und sie in asynchroner Weise laden. Wenn Sie schauen auf Google Street View, wie es lädt, nach Zoom, wil Sie herausfinden, dass nie gesamtes Bild (auch wenn es von Ihnen angeforderte wurde) sofort geladen, aber es belastet durch Sektoren.
Eine weitere sehr interessante Technologie Ich denke, Deep Zoom kann sein, wenn nicht eine Antwort auf Ihre Probleme, aber kann zumindest einen guten Hinweis geben.
Ein weiteres Beispiel auf Deep Zoom von Scott Hanselman
Viel Glück.
So pervers dies klingt, Sie sollten versuchen, alle Daten in den Speicherabbilddateien beim Start Ihrer Anwendung zu berühren (d. h. ein Byte bei jedem Vielfachen von 4 KB ab dem Beginn jeder Datei zu lesen). Da Sie genug RAM haben, ist das Problem wahrscheinlich nicht, dass das Betriebssystem Ihre Bilder ausblättert, sondern dass es sie nicht zuerst einblendet. Speicherkarten sind ladend geladen, so dass das Betriebssystem die Festplatte erst trifft, wenn Sie es tatsächlich versuchen Greifen Sie auf die Daten in den Memory-Mapped-Dateien zu. Als Ergebnis führt das Berühren des Speichers beim Laden der Anwendung dazu, dass die Plattenlesevorgänge dann statt der Zeit stattfinden, wenn der Benutzer Bildstapel betrachtet.
Je nachdem, wie groß die Anzeige und die Bilder sind, können Sie versuchen, die Bilder so zu verkleinern, dass sie der Auflösung des Quadrats entsprechen. Wenn Sie dann auf einen Punkt des Bildes fokussieren möchten, können Sie das Bild erneut laden Originalbild.
Wenn Sie WPF verwenden, können Sie versuchen, DecodePixelWidth und DecodePixelHeight zu verwenden. Vielleicht gibt es ein Äquivalent in winforms
Tags und Links .net c# image-processing memory-management parallel-processing