Ned Flanders schrieb:
Also mal abgesehen von bestimmten Gaming Engines lässt sich das meiste, was zeitkritisch ist, doch wunderbar zerlegen. Und beim Gaming gehts mit Vulcan und DX12 auch vorran.
Ganz pauschal kann man das auf jeden Fall mit "nein" beantworten.
Dein folgendes Beispiel zeigt, dass du bei Parallelisierung zu abstrakt denkst. EIn konkretes Beispiel für deine Sicht wäre z.B. das Schreiben eines berechneten Ergebnisses in zwei verschiedene Dateien. Zwei Operationen, die man bedenkenlos parallel ausführen kann.
Das ist auch genau das was man heute bei einfachem Multi-Threading macht. Man sagt dem Compiler führe bitte diese Funktion in einem Thread aus und die andere in einem zweiten.
Damit hat man aber mit Glück nur vielleicht die ersten 5% bis 10% des Programms parallelisiert. Daher gibt es verschiedene Techniken - die mir nicht bekannt sind - mit denen man ein Programm analysieren kann, um festzustellen, welche CPU-Befehle in welcher Beziehung zueinander stehen und wo Abhängigkeiten bestehen. Du merkst vielleicht schon, dass wir jetzt schon von einer ganz anderen Ebene der Programmierung sprechen. Eben waren wir noch bei einer sehr abstrakten, i.d.R. objektorientierten Programmierung. Jetzt sind wir beim CPU-Befehlssatz und analysieren Abhängigkeiten von Aufrufen an die CPU. Das ist zum einen sehr schwierig und erfordert absolute Experten in ihrem Gebiet und zum anderen haben auch diese Techniken sehr früh ihre Grenzen. Ein Programm muss immer zwingend einen seriellen Teil haben (ist ja logisch) und normalerweise ist dieser Anteil sogar >50%. Das kommt im konkreten Fall natürlich aber, wie du ja schon sagst, auf die Anwendung an. Ich würde mal schätzen, dass du insgesamt über eine gesamte Anwendung hinweg gesehen nie unter 30% kommen kannst (man möge mich korrigieren, sofern es Blödsinn ist).
Zuletzt muss man sich dann als Entwickler auch immer fragen, ob und wann parallele Ausführung überhaupt Sinn ergibt. Das Problem dabei ist, dass jede parallele Ausführung einen gewissen Overhead und/oder Wartezeit mit sich bringt. Overhead im Sinne von "da muss ein Thread erstellt und Daten übertragen werden" und Wartezeit im Sinne von "ich erwarte ein Ergebnis von meinen 800 Threads".
Wie du siehst ist das Thema nicht so leicht und meiner Einschätzung nach, haben wir hier bereits mehr oder weniger das Optimum erreicht bei den meisten Anwendungen. Ein kleiner Lichtblick ist eventuell noch die sogenannte Funktionale Programmierung, das ist ein Programmierstil, der sich vom üblichen Stil deutlich unterscheidet, da er (vereinfacht gesagt) nur Funktionsaufrufe und keine Variablen oder ähnliches kennt. Das besondere ist hier, dass jedes Programm, dass in einer rein funktionalen Sprache (z.B. Haskel) geschrieben ist, vom Compiler ganz automatisch und ohne weiteres Zutun so weit wie nur irgendwie möglich parallelisiert werden kann. Das ist leider aber natürlich auch kein Allheilmittel, aber das ist nun ein GANZ anderes Thema