Wie würde sich eine CPU, die ausschließlich für die funktionale Programmierung ausgelegt ist, unterscheiden?

14

CPUs sind zu einem gewissen Grad unter Berücksichtigung der Software konzipiert, die die Leute implizit oder explizit dafür schreiben.

Wenn Sie sich den Entwurf von Befehlssatzarchitekturen ansehen, scheint es mir, dass sie sehr "zwingend" sind, in dem Sinne, dass jeder Befehl einen Befehl im imperativen Stil codiert. Es scheint mir auch, dass sich die aktuellen Befehlssatzarchitekturen teilweise basierend auf der Art des Code-Programmierers entwickelt haben.

Wenn man eine CPU von Grund auf neu entwerfen würde, wenn man wüsste, dass sie nur Programme ausführen würde, die in einem funktionalen Programmierstil geschrieben sind, wie würde diese CPU anders als die existierenden CPUs aufgebaut sein?

user56834
quelle
9
John Backus in seiner "Kann Programmierung vom von Neumann-Stil befreit werden?" erwähnt nur wenige solcher Werke (Abschnitt 15).
Dmitri Urbanowicz
Suchen Sie nach (grafischen) Reduktionsmaschinen oder besuchen Sie Ihre lokale Forschungsbibliothek in der Hoffnung, ein Exemplar von W. Kluges vergriffenem Buch Die Organisation von Reduktions-, Datenfluss- und Kontrollflusssystemen (MIT Press, 1992) zu finden.
Kai
2
Auch Koopmans Buch An Architecture for Combinator Graph Reduction (AP, 1990). Ein Blick in Lisp-Maschinen lohnt sich wahrscheinlich auch. en.wikipedia.org/wiki/Lisp_machine
Pseudonym
Ich denke, unsere Maschinen werden im Laufe der Zeit immer unabdingbar sein und ihren Zustand verändern.
Orlp
Ein paar nützliche CPU-Funktionen wären native Unterstützung für Thunks und effizienteres Springen. Außerdem kann die CPU möglicherweise einige Verknüpfungen ausführen, wenn sie weiß, dass bestimmte Speicherorte in einem bestimmten Bereich nicht überschrieben werden und die CPU keinen Stack auf die gleiche Weise wie in stapelbasierten Sprachen verwalten muss.
Setzen Sie Monica

Antworten:

2

Eigentlich wurde es gemacht: https://en.wikipedia.org/wiki/Lisp_machine

Ein Aspekt im CPU-Design für FP ist die Speicherbereinigung. GC ist sehr wichtig für funktionale Sprachen. Gängige Implementierungen erfordern, dass der GC zwischen Zeigern und Nicht-Zeiger-Daten unterscheiden kann. Tatsächlich bedeutet das, ein zusätzliches Bit in Ihren Daten zu speichern. Dies ist der Grund, warum beispielsweise OCaml-Ganzzahlen auf 32-Bit-Architekturen nur 31-Bit und auf 64-Bit-Architekturen nur 63-Bit sind. Ganzzahlige Arithmetik beinhaltet dann umständliche zusätzliche Verschiebevorgänge. Andere Sprachen (oder andere OCaml-Datentypen) verschwenden möglicherweise ganze Maschinenwörter für dieses zusätzliche Bit und verwenden daher 128 Bit für 64-Bit-Ganzzahlen. Eine CPU, die von Haus aus auf GC ausgelegt ist, verfügt möglicherweise über einen 65-Bit-Datenbus, jedoch über 64-Bit-Arithmetik.

Allerdings haben viele nicht funktionierende Sprachen auch eine Garbage Collection und würden daher von entsprechenden Architekturen profitieren.

Eine andere Sache, die mir einfällt, ist die Tatsache, dass die Speichernutzung von FP in der Regel viel stärker gestreut ist als die von imperativen Programmen. Hauptsächlich, weil es weniger natürlich ist, Arrays zu verwenden. Infolgedessen profitieren diese Programme weniger davon, zusammenhängende Speicherbereiche zwischenzuspeichern. Eine FP-CPU kann also unterschiedliche Caching-Strategien verwenden.

Knie
quelle
1

Es würde entweder nichts ändern oder massive Paralleleinstellungen wie bei Reduceron und seinem Nachfolger PilGRIM 1 mit einem riesigen Stapel nutzen.

Die Aussage, dass sich nichts ändern würde, erscheint zunächst kühn, aber da die CPU sequenziell ist, gibt es einen Übersetzungsprozess (Kompilierung), der die verfügbare Hardware aus Effizienzgründen in vollem Umfang nutzt. Sollte es eine andere Architektur geben, wären einige Vorgänge schneller, andere benötigen Hacking-Tricks, um sie zu beschleunigen.

Architektur, die einen Unterschied machen würde, würde eine schnellere Ausführung von Kartenoperationen und Listen erfordern (nicht die gesamte Story, aber es reicht aus, um den Effekt zu zeigen). Es gibt keine Möglichkeit, sich dynamisch ändernde Hardware zu erstellen, um Listen nativ auszuführen, sodass diese in einem zusammenhängenden Speicher abgelegt werden. Wir bleiben bei der Array-Darstellung irgendeiner Form. Damit die Karte in einer nicht sequentiellen Einstellung ausgeführt werden kann, kehren wir zu Reduceron zurück. So effektiv eine zentrale Verarbeitung für aufeinanderfolgende Anweisungen und Unterstützung für die parallele Verarbeitung.

Was möglicherweise anders ist, ist die Möglichkeit, mehrere Funktionen zu laden und auszuführen, ohne dass Frames jonglieren müssen. Wenn Sie jedoch mehrere Einheiten für Funktionen hinzufügen, wird der Zugriff auf den Speicher beeinträchtigt.

Zur Antwort von kne hinzufügen, wäre es von Vorteil, den GC als Coprozessor zu betreiben, es wäre eine sehr nette Funktion.

1: PilGRIM ist in Boeijink A., Hölzenspies PKF, Kuper J. (2011) beschrieben. In: Hage J., Morazán MT (Hrsg.) Implementierung und Anwendung funktionaler Sprachen. IFL 2010. Lecture Notes in Computer Science, Bd. 6647. Springer, Berlin, Heidelberg .

Böse
quelle
Msgstr "Es gibt keine Möglichkeit, die Rekursion nativ zu machen". Können Sie erklären, warum das so ist? Das kommt mir zunächst überraschend vor.
User56834
Ist das Reduceron auch etwas, das eine harte CPU sein könnte, anstatt auf einer FPA zu laufen?
User56834
Meine schlechte, ich meinte native Rekursion , aber es ist wahrscheinlich irrelevant. Ich muss ein bisschen überarbeiten.
Evil
0

Zunächst ein kleiner Witz: Da das Ausführen eines 100% igen Funktionsprogramms niemals etwas Nützliches bewirken kann, würde es genügen, nur eine NOP-Anweisung zu haben. (Ich öffne das für Flammenkriege).

Es wird also einige wichtige Anweisungen für IO und die übliche Unterstützung für die imperative Programmierung geben müssen.

Ansonsten hängt es teilweise von der tatsächlich verwendeten Sprache ab. Die beiden, die ich im Kopf habe, sind Haskell und Erlang.

Ich würde glauben, dass Haskell von der Unterstützung für Listen und Karten profitieren könnte. Eine Liste könnte durch bestimmte Hardware-Speicherzuordnungen unterstützt werden, wodurch die verknüpfte Liste in einen aufeinanderfolgenden Satz von Adressen umgewandelt wird. Das erste Element könnte an der Adresse n sein, das zweite an der Adresse n + 1 und so weiter. Um das erste Element aus der Liste zu entfernen, ändern Sie einfach den Zeiger n. Wenn Sie schließlich den Zeiger n löschen, kann der gesamte Speicher freigegeben werden. Maps können als assoziative Arrays unterstützt werden. Geben Sie den Suchwert ein, und das Speichersystem gibt den Artikel zurück. Keine Notwendigkeit für iterative Suchen.

Erlang wiederum könnte von der Unterstützung von Nachrichten / Prozessen und der Endrekursion mit vollem Status profitieren. Nachrichten und Prozesse können auf verschiedene Arten unterstützt werden, beispielsweise durch eine extrem große Anzahl von Prozessorkernen. Die Schwanzrekursion könnte durch eine Speichersteuerung verbessert werden, die weiß, dass der Zustand viel schneller kopiert werden kann, wobei möglicherweise keine großen Datenmengen kopiert werden, sondern lediglich die Zeiger des Speichersystems geändert werden.

Ghellquist
quelle