In allen anderen hier vorgestellten Antworten geht es um buchstäbliche Unterschiede zwischen FPGAs und CPUs. Sie verdeutlichen die Parallelität des FPGAs gegenüber der sequentiellen Natur einer CPU oder geben Beispiele dafür, warum bestimmte Algorithmen auf einem FPGA möglicherweise gut funktionieren. All dies ist gut und wahr, aber ich würde vorschlagen, dass es einen grundlegenderen Unterschied zwischen CPUs und FPGAs gibt.
Was ist der gemeinsame Nenner zwischen einem FPGA und einer CPU? Es ist so, dass beide auf Silizium aufgebaut sind. Und in einigen Fällen buchstäblich die gleichen Siliziumprozesse.
Der fundamentale Unterschied sind die Abstraktionen, die wir auf dieses Silizium stapeln. Es ist für einen Menschen nicht möglich, alle Details eines einzelnen modernen CPU-Designs vom Silizium bis zum IC-Gehäuse zu verstehen. Als Teil des Entwicklungsprozesses teilen wir dieses komplexe Problem in kleinere handhabbare Probleme auf, mit denen sich Menschen beschäftigen können.
Überlegen Sie, was erforderlich ist, um das Silizium in eine funktionierende CPU zu verwandeln. Hier ist eine etwas vereinfachte Ansicht der Abstraktionsebenen, die für dieses Ziel erforderlich sind:
Zuerst haben wir Ingenieure, die wissen, wie man Transistoren aus Silizium herstellt. Sie wissen, wie man winzige Transistoren entwickelt, die 10 oder sogar 100 Gigahertz Strom verbrauchen und schalten, und sie wissen, wie man leistungsfähige Transistoren entwickelt, die Signale mit ausreichender Leistung aus einem IC-Gehäuse und über eine Leiterplatte senden können zu einem anderen Chip.
Dann haben wir digitale Logikdesigner, die wissen, wie man diese Transistoren zu Bibliotheken mit Hunderten verschiedener Logikzellen zusammensetzt. Logikgatter, Flip-Flops, Muxes und Addierer, um nur einige zu nennen. Alles in einer Vielzahl von Konfigurationen.
Als nächstes haben wir verschiedene Gruppen von Ingenieuren, die wissen, wie diese digitalen (und manchmal analogen) Blöcke zusammengesetzt werden, um Funktionsblöcke höherer Ebene wie Hochgeschwindigkeitstransceiver, Speichercontroller, Verzweigungsvorhersagen, ALUs usw. zu bilden.
Dann haben wir CPU-Designer, die High-End-CPU-Designs entwerfen, indem sie diese Funktionseinheiten zu einem vollständigen System zusammenfassen.
Und hier hört es nicht auf. Zu diesem Zeitpunkt haben wir eine funktionierende CPU, die Assembler-Code ausführt, aber das ist keine Sprache, die die meisten Programmierer heutzutage schreiben.
- Wir könnten einen C-Compiler haben, der zu Assembler-Code kompiliert (wahrscheinlich durch eine Zwischendarstellung)
- Wir könnten eine weitere Abstraktion über C einfügen, um eine objektorientierte Sprache zu erhalten
- Möglicherweise schreiben wir sogar eine virtuelle Maschine auf C oder C ++, damit wir Dinge wie Java-Bytecode interpretieren können
Und von dort aus können die Abstraktionsschichten weitergehen. Der wichtige Punkt hierbei ist, dass diese Abstraktionsschichten zusammen ein CPU-basiertes System ergeben, das massiv skaliert und einen winzigen Bruchteil eines kundenspezifischen Siliziumdesigns kostet.
Wichtig hierbei ist jedoch, dass jede Abstraktion für sich genommen auch Kosten verursacht. Der Transistordesigner baut nicht für jeden Anwendungsfall den perfekten Transistor. Er baut eine vernünftige Bibliothek auf, und so wird manchmal ein Transistor verwendet, der etwas mehr Energie oder etwas mehr Silizium verbraucht, als für die eigentliche Aufgabe benötigt wird. In ähnlicher Weise bauen die Logikdesigner nicht jede mögliche Logikzelle. Sie könnten ein NAND-Gatter mit 4 Eingängen und ein NAND-Gatter mit 8 Eingängen bauen, aber was passiert, wenn ein anderer Ingenieur ein NAND mit 6 Eingängen benötigt? Er verwendet ein NAND-Gatter mit 8 Eingängen und bindet 2 unbenutzte Eingänge ab, was zu einem Verlust der Siliziumressourcen und einem Leistungsverlust führt. Und so geht es die Kette der Abstraktionen hinauf. Jede Schicht gibt uns einen Weg, mit der Komplexität umzugehen,
Vergleichen Sie nun diese Abstraktionen mit dem, was für ein FPGA benötigt wird. Im Wesentlichen hören die FPGA-Abstraktionen bei # 2 in der obigen Liste auf. Mit dem FPGA können Entwickler auf der digitalen Logikebene arbeiten. Es ist etwas ausgefeilter als das, weil CPUs auf dieser Ebene 'fest codiert' sind und FPGAs zur Laufzeit konfiguriert werden müssen (was übrigens der Grund ist, warum CPUs normalerweise viel höhere Frequenzen ausführen), aber die wesentliche wichtige Wahrheit ist, dass diese weit entfernt sind wenige Abstraktionen für FPGAs als für CPUs.
Also, warum kann ein FPGA schneller als eine CPU? Das liegt im Wesentlichen daran, dass das FPGA weitaus weniger Abstraktionen verwendet als eine CPU, was bedeutet, dass der Designer näher am Silizium arbeitet. Er zahlt nicht die Kosten für all die vielen Abstraktionsschichten, die für CPUs erforderlich sind. Er codiert auf einer niedrigeren Ebene und muss härter arbeiten, um ein bestimmtes Maß an Funktionalität zu erreichen. Als Belohnung erhält er jedoch eine höhere Leistung.
Aber es gibt natürlich auch eine Schattenseite für weniger Abstraktionen. All diese CPU-Abstraktionen gibt es aus gutem Grund. Sie geben uns ein viel einfacheres Codierungsparadigma, was bedeutet, dass sich mehr Menschen leicht für sie entwickeln können. Dies wiederum bedeutet, dass es viel mehr CPU-Designs gibt und wir somit massive Vorteile in Bezug auf Preis / Skalierung / Time-to-Market von CPUs haben.
Also da hast du es. FPGAs haben weniger Abstraktionen und sind daher schneller und energieeffizienter, aber schwer zu programmieren. CPUs haben viele Abstraktionsdesigns, um sie einfach zu entwickeln, skalierbar und kostengünstig zu machen. Aber sie geben Geschwindigkeit und Macht im Handel für diese Vorteile auf.