Was sind genau die Unterschiede zwischen Unified Memory und HUMA?
HUMA ist bzw. soll allgemeiner werden, als Unified Memory von NVIDIA im Moment ist, wobei NVIDIA ebenfalls sein Unified Memory ausbauen will.
HUMA soll meines Wissenstands nach in der fertigen Version bewirken, dass sowohl GPU und CPU gegenseitig jederzeit auf ihren gesamten Hauptspeicher (auch den ausgelagerten auf der Festplatte) zugreifen können, und dass deshalb sämtliche Cache untereinander cohärent gehalten werden.
Unified Memory in NVIDIA ist momentan etwas eingeschränkter. Es gibt zwei Möglichkeiten wie sich GPU und CPU einen Speicherbereich teilen können: Über pinned Memory und über Managed Memory. Versucht man andersweitig von der GPU aus auf den CPU-Speicher zuzugreifen oder Vize-Versa kommt es zu einem Programmabsturz per Segfault.
Bei Pinned Memory handelt es sich um Speicher im DRAM der CPU, welcher nicht auf die Festplatte ausgelagert werden darf und auf welchen PCI-E-Geräte schnell per DMA zugreifen können. Dieser Speicher ist in CUDA sowohl von der CPU als auch von der GPU aus über die selben virtuellen Addressen ansteuerbar, muss aber extra über einen extra Befehl alloziert werden. Dadurch kann man eine zeigerbasierte Datenstruktur, welche man im Pinned Memory im Host baut, ebenfalls auf der GPU verwenden und Vize-Versa.
Ein ähnlicher pinned Memory existiert ebenfalls bei AMD, wobei es mir hier etwas unklar ist ob die Radeon GPUs ebenfalls die selben virtuellen Addressen wie der Host verwenden, da man für deren Programmierung nur OpenCL verwenden kann, und OpenCL Kernels "keine Zeiger" sondern nur Buffer unterstützen.
Managed Memory ist ebenfalls sehr eingeschränkt im Vergleich zu HUMA. Hier hat es jemand mal beschrieben, wie es genau funktioniert, und was für Nachteile es hat:
https://devtalk.nvidia.com/default/topic/695408/first-impressions-of-cuda-6-managed-memory/
Eben deshalb gilt, dass der gemeinsame Speicherzugriff bei CUDA momentan im Vergleich zur finalen Version von HUMA etwas eingeschränkt ist.
Das kann man so pauschal nicht sagen. Fermi hat einen Hardware-Scheduler, bei Kepler hingegegen ist der Scheduler in die Software gewandert.
Da ich von offizieller Seite dazu nie etwas gelesen habe und es mir gemäß meines Wissenstands nicht plausibel erscheint, handelt es sich bei dieser Aussage vermutlich um ein Grücht.
Denn das Thread-Scheduling auf GPUs findet auf zwei Ebenen statt: Dem Thread-Block-Scheduling und dem Warp-Scheduling. Dabei ist ein Thread-Block eine Gruppe von N Warps, welche immer von einem Multiprozessor abgearbeitet wird. Will man auf der GPU etwas berechnen so startet man eigentlich viele Threadblocks (auch ein Gitter an Thread-Blocks genannt). Ein Thread-Block wird von dem Thread-Block-Scheduler der GPU einem Multiprozessor zugewiesen, sofern dort ein freier Platz für ihn ist. Der Thread-Block bleibt so lange auf diesem Multiprozessor bis alle seine Threads fertig sind. Jeden Takt wählt nun ein Multiprozessor mehrere Warps von den Thread-Blocks, die er gerade beherbergt aus, und gibt deren nächsten Befehl in Auftrag (Warp-Scheduling). Da insbesondere das Warp-Scheduling aber auch das Thread-Block-Scheduling sehr schnell gehen müssen, ist da keine Zeit etwas per Software (außer evtl in der Form von Mikrocode) zu bestimmen; zumal es äußerst ineffizient wäre solche häufigen Berechnungen per Software durchzuführen. Deshalb ist das in Hardware implementiert (siehe zum Beispiel GK 110 Whitepaper über die entsprechende Scheduling-Hardware). Dies äußert sich auch in den Hardwarelimitierungen von GPUs, wie der maximalen Occupancy oder der maximalen Größe des Thread-Block-Gitters.
das sollte aber an der Latenz nichts ändern. Und siehe auch viele Threads = viele Zwischenergebnisse = extremer Speicherzugriff und Verbrauch wenn ich Nai richtig verstanden habe.
Das ist korrekt.