LONy hat geschrieben:Hm, die Frage ist ja, welche (mathematischen) Probleme sich wie aufteilen lassen, um sie überhaupt zu parallelisieren.
Es müsste denke ich eine Mischung aus paralleler und sequentieller Programmierung dabei herraus kommen.
Richtig. Das ist auch meine Grundidee.
LONy hat geschrieben:
Ein digitaler Filter (FIR) lässt sich gut parallelisieren, allerdings müssen x Werte (je nach Filterordnung) gleichzeitig zur Verfügung stehen. Ich weiß nicht, wie das in einer GraKa organisiert ist, die ja schon stark parallel arbeitet, allerdings ist bei einer normalen Multicore CPU hier denk ich der RAM der Flaschenhals... Die Architektur müsste sich wohl für so eine Programmiersprache auch ändern? In Richtung FPGA, was dann allerdings auch nur wieder sehr spezielle Problemstellungen betrifft.
Die Sprache sollte nach Möglichkeit nicht auf Shared Memory angewiesen sein. Dass Aufgaben auf komplett andere Knoten abgewälzt werden und eine Netzwerkverbindung an Bandbreite genügen muss, ist die große Kunst daran. Und genau hier muss man sehen, auf welcher Ebene man ansetzt, wie feingranular man also das System baut. Am Ende muss man genau den Punkt finden, wo die wenigsten Daten zur Kommunikation gebraucht werden und setzt dort die Grenze.
LONy hat geschrieben:
Einen Programmablauf programmiert man allerdings leichter in einer klassischen sequentiellen Sprache, nicht umsonst haben FPGAs kleine Softcores von normalen Mikrocontrollern, da man bei umfrangreichen Statemachines schnell im VHDL code ersticken würde ;)
Das sehe ich anders. Ein Programmablauf ist heutzutage eher eventgetrieben. Das kann man prima parallelisieren, wenn die Elemente sich denn nicht auf der Low-Level Ebene im Speicher so behaken würden. "Unten" macht e dann eher Sinn, sequenzielle Programme zu haben, weil das immer noch die effizienteste Methode auf heutigen SMP-Systemen ist.
LONy hat geschrieben:
Der beste Ansatz währe wohl ein ereignisgesteuertes System, bei der man jeden Programmschritt in kleien Tasks aufteilen kann, die dann alle auf einem extra Kern ablaufen können... ich denke da z.B. an ein Spiel, bei dem alle Objekte nach Objekten in ihrer Umgebung suchen.. normal würde ich eine zweifach verschachtelte schleife Programmieren, wo der Abstand zwischen jedem Objekt berechnet wird (pseudocode):
Code: Alles auswählen
for(i=0;i<max;i++)
for(j=0;j<max;j++)
if(i!=j)
if(berechne_abstand(i,j)<100)
tu_was()
Ausführung nur auf einem Kern... sehr langsam. Besser wäre denke ich die äußere Schleife auf alle vorhandenen Kerne aufzuteilen (und vielleicht sogar die innere?)
Ich finde, an dem Punkt darf man auf der äußeren Ebene nicht mehr von "Schleifen" reden, denn Schleifen sind ein sequenzielles Konstrukt. Besser wären Batches, also Stapel von unterschiedlichen Parametern, die alle in denselben Closure eingeführt werden. Map Reduce funktioniert auch nach diesem System.
LONy hat geschrieben:
Code: Alles auswählen
starte_neue_prozesse(max)
for(j=0;j<max;j++)
if(j!=Prozessnummer)
if(berechne_abstand(prozessnumer,j)<100)
tu_was()
tu_was() müsste hier natürlich jeweils wieder automatisch in einem neuen Prozess gestartet werden (wenn tu_was() sehr häufig aufgerufen wird) Die frage ist hier denke ich, wie kann ich allen Prozessen die entscheidenden Daten (z.B. die koordinaten der objekte) gleichzeitig bereit stellen. Man bräuchte eine art Multiport RAM, der so viele Ausgänge hat, wie prozessorkerne auf ihn zugreifen können.
Dabei dachte ich auch an eine Prozessorarchitektur, die nicht mehr nach Kernen, sondern nach RAM-Blöcken aufgeteilt ist. Anstatt Cachelines zu den Kernen zu bewegen, werden Threads zum richtigen RAM-Abschnitt bewegt. Resultat: man kann viel mehr Threads gleichzeitig starten (im Idealfall alle, die das Betriebssystem gerade ausführt), die Single Core Performance ist allerdings etwas geringer; Caches und Kohärenz-Probleme gehören der Vergangenheit an, da ja jeder RAM-Block nur einen Thread gleichzeitig an sich ranlässt. (Hat ein Thread allen Speicher, wird er im Chip dann in einen Bereich bewegt, wo sich ALUs befinden, um seine Rechnungen abzuarbeiten)
Alternativ kann man auch statt großen Knoten viele kleine Rechner benutzen, wo ebenfalls die Devise gilt: Das Programm muss zu den Daten und nicht anders herum.
LONy hat geschrieben:
wenn tu_was() nur als singleprozess abläuft und ansonsten in einer Warteschlange kommt, hätte man keine Probleme mit gleichzeitig anstehenden Ergebnissen... ansonsten müsste die Sprache befehle bereit stellen, welches Ergebnis bevorzugt wird, oder, dass in einem weiteren Thread die Ergebnisse verrechnet werden und so lange weitere Threads gestartet werden, bis nur noch ein Thread genau ein ergebnis liefert, welches dann zur weiteren Bewertung / Verarbeitung in einen dieser Multiport RAMs geschrieben wird...
Durchsteig' ich momentan nicht. Ich finde ja, der Programmierer sollte sich nicht um Speicherlokalität kümmern, sondern der Scheduler der Sprache sollte das gut abschätzen.
LONy hat geschrieben:
Soweit mein Beitrag erstmal zum Brainstorming :D Ich kann sowohl gut C++ als auch VHDL, hab allerdings von Grafikprogrammierung auf der Graka keinen blassen Schimmer... vielleicht wird es da ja schon lange so gemacht^^ Ich hoffe meine wirren Gedanken bringen dich ein Stück weiter ;)
Auf alle Fälle.
Naja die GRAKAs haben massive Hyperthreading, Memory-Fetch-Abschnitte im Programmabfluss und Rechen dann Stöße von Aufgaben, sobald genug Speicher da ist. Im Allgemeinen ist aber paralleles Programmieren mit OpenCL oder CUDA noch nicht die reine Intuition eines Programmierers und benötigt immer noch einen Orchestrierer, der den GPU-State aufsetzt und die Kernel startet (die alle denselben Code haben müssen).