"Ich habe gelesen, dass F1-Autos schneller sind als die, die wir auf der Straße fahren ... warum benutzen die Leute dann keine F1-Autos?" Nun ... Die Antwort auf diese Frage ist einfach: F1-Autos können nicht so schnell brechen oder drehen wie die meisten Autos (in diesem Fall könnte das langsamste Auto eine F1 schlagen). Der Fall von GPUs ist sehr ähnlich. Sie können einer geraden Verarbeitungslinie folgen, aber sie sind nicht so gut, wenn es um die Auswahl verschiedener Verarbeitungspfade geht.
Ein in der GPU ausgeführtes Programm ist sinnvoll, wenn es mehrere Male parallel ausgeführt werden muss, z. B. wenn Sie alle Pixel aus Textur A mit Pixeln aus Textur B mischen und sie alle in Textur C einfügen müssen Eine CPU würde wie folgt verarbeitet:
for( int i =0; i< nPixelCount; i++ )
TexC[i] = TexA[i] + TexB[i];
Dies ist jedoch langsam, wenn Sie viele Pixel verarbeiten müssen, sodass die GPU anstelle des obigen Codes nur den nächsten verwendet:
TexC[i] = TexA[i] + TexB[i];
Anschließend werden alle Kerne mit diesem Programm gefüllt (dh das Programm wird im Wesentlichen in den Kern kopiert), und i
für jeden wird ein Wert zugewiesen. Dann kommt die Magie von der GPU und alle Kerne führen das Programm zur gleichen Zeit aus , wodurch viele Operationen viel schneller ausgeführt werden, als es das lineare CPU-Programm tun könnte.
Diese Arbeitsweise ist in Ordnung, wenn Sie sehr viele kleine Eingaben auf die gleiche Weise verarbeiten müssen, aber wirklich schlecht, wenn Sie ein Programm erstellen müssen, das möglicherweise eine bedingte Verzweigung aufweist. Nun wollen wir sehen, was die CPU macht, wenn es um eine Zustandsprüfung geht:
- 1: Führen Sie das Programm bis zur ersten logischen Verknüpfung aus
- 2: Auswerten
- 3: Fortsetzung der Ausführung aus dem Speicheradressenergebnis des Vergleichs (wie bei einem JNZ-asm-Befehl)
Dies ist sehr schnell, wenn die CPU einen Index festlegt, aber wenn die GPU dasselbe tut, ist es viel komplizierter. Da der Strom von der GPU aus der Ausführung derselben Anweisung zur selben Zeit stammt (es handelt sich um SIMD-Kerne), müssen sie synchronisiert werden, um die Vorteile der Chiparchitektur nutzen zu können. Die GPU auf den Umgang mit Branchen vorbereiten zu müssen, bedeutet mehr oder weniger:
- 1: Erstellen Sie eine Version des Programms, die nur auf Zweig A folgt, und füllen Sie diesen Code in allen Kernen aus.
- 2: Führen Sie das Programm bis zur ersten logischen Verknüpfung aus
- 3: Alle Elemente auswerten
- 4: Fahre mit der Verarbeitung aller Elemente fort, die der Verzweigung A folgen, und reihe alle Prozesse ein, die Pfad B gewählt haben (für die es kein Programm im Kern gibt!). Jetzt sind alle Kerne, die Pfad B gewählt haben, LEER !! - der schlimmste Fall ist, dass ein einzelner Kern ausgeführt wird und jeder andere Kern nur wartet.
- 5: Aktivieren Sie nach Abschluss der Verarbeitung die Zweig-B-Version des Programms (indem Sie sie aus den Speicherpuffern in einen kleinen Kernspeicher kopieren).
- 6: Zweig B ausführen
- 7: Mischen Sie bei Bedarf beide Ergebnisse.
Diese Methode kann aufgrund vieler Faktoren variieren (z. B. aufgrund einiger sehr kleiner Faktoren)Verzweigungen können ohne diese Unterscheidung ausgeführt werden. Jetzt können Sie jedoch bereits erkennen, warum Verzweigungen ein Problem darstellen. Die GPU-Caches sind sehr klein. Sie können ein Programm nicht einfach linear aus dem VRAM ausführen. Sie müssen kleine Anweisungsblöcke auf die auszuführenden Kerne kopieren. Wenn Sie genügend Verzweigungen haben, wird Ihre GPU meistens blockiert als ausgeführt jeder Code, der keinen Sinn ergibt, wenn ein Programm ausgeführt wird, das nur einem Zweig folgt, wie es die meisten Programme tun - auch wenn es in mehreren Threads ausgeführt wird. Im Vergleich zum F1-Beispiel bedeutet dies, dass Sie in jeder Kurve Bremsfallschirme öffnen und dann aus dem Auto aussteigen müssen, um sie wieder im Auto zu verstauen, bis Sie in die nächste Kurve einbiegen möchten, oder ein rotes Semaphor (die nächste Kurve) finden müssen höchstwahrscheinlich).
Dann gibt es natürlich das Problem, dass andere Architekturen für logische Operationen so gut geeignet sind, weitaus billiger und zuverlässiger, standardisierter, bekannter, energieeffizienter usw. Neuere Videokarten sind ohne Software-Emulation kaum mit älteren kompatibel Verwenden Sie unterschiedliche ASM-Anweisungen, auch wenn sie vom selben Hersteller stammen. Derzeit erfordern die meisten Computeranwendungen keine solche parallele Architektur. Selbst wenn sie diese benötigen, können sie über Standard-APIs wie OpenCL as verwendet werden Erwähnt durch eBusiness oder durch die Grafik-API. Wahrscheinlich werden wir in einigen Jahrzehnten GPUs haben, die CPUs ersetzen können, aber ich glaube nicht, dass dies in Kürze geschehen wird.
Ich empfehle die Dokumentation der AMD APP, die viel über ihre GPU-Architektur erklärt, und ich habe auch die NVIDIA in den CUDA-Handbüchern gesehen, was mir sehr geholfen hat, dies zu verstehen. Ich verstehe immer noch einige Dinge nicht und kann mich irren. Wahrscheinlich kann jemand, der mehr weiß, meine Aussagen bestätigen oder ablehnen, was für uns alle großartig wäre.