Weißbuch

Beschleunigung von 2D-FFTs

Verwendung von HBM2 und oneAPI auf Stratix 10 MX

Übersicht

FPGAs mit HBM2-Speicher sind schneller als GPU-Chips, wenn Algorithmen "Corner Turns" enthalten. Dies liegt daran, dass der FPGA die Eckumkehrung mit der Berechnung überlappen kann, wodurch sie aus Sicht der Latenzzeit "frei" ist. Wir demonstrieren diese Technik anhand einer 2D-FFT und stellen den Quellcode unten zur Verfügung. Um die Dinge "fair" zu halten, verwendet dieser Code einen Datentyp, den auch GPUs unterstützen. FPGAs können problemlos jeden Datentyp verarbeiten. 

BittWare hat bereits einen 2D-FFT-Kernel für FPGAs unter Verwendung des OpenCL-Compilers von Intel entwickelt. Wir haben diesen Code nun umgeschrieben, um Intels oneAPI-Programmiermodell, insbesondere die Programmiersprache DPC++, zu nutzen. Wir haben die gleiche Leistung auf unserer 520N-MX-Karte erreicht. Intel bewirbt oneAPI als die beste Toolchain für Anwendungen, die GPU- oder FPGA-Beschleunigung erfordern.

Warum haben wir eine 2D-FFT implementiert?

Die 2D-FFT ist häufig in FPGA-IP-Bibliotheken enthalten und wird daher im Allgemeinen nicht von Programmierern selbst implementiert. Eine gängige Implementierungsstrategie für 2D-FFT auf paralleler Hardware beinhaltet jedoch einen "Corner-Turn"- oder "Datentranspositions"-Schritt, der auf CPUs und GPUs einen großen Leistungsengpass darstellt.

Freie Kurvenfahrt

Die Einsicht, die wir in dieser Demonstration hervorheben, ist, dass eine FPGA-Implementierung die Datentransposition parallel zu den Berechnungen durchführen kann, was sie aus Sicht der Latenzzeit fast "kostenlos" macht.

Ein Grafikprozessor kann nicht dasselbe tun, da die Grafikprozessorarchitekturen nicht über genügend Speicher innerhalb des Grafikprozessors verfügen, um Zwischenergebnisse in einer Pipeline zu verarbeiten, ohne den HBM2/GDDR6-Speicher anzufassen.

Illustration einer 2D-FFT, die mit zwei Durchläufen einer 1D-FFT mit Eckumkehrungen implementiert wurde.

Verwendung von HBM2 auf FPGAs mit oneAPI

Der Stratix 10 MX hat 32 Pseudo-HBM2-Speicherkanäle. Unsere 2D-FFT-Implementierung verwendet die Hälfte dieser Kanäle.
  • Wir können zwei 2D-FFT-Kernel auf dem Chip platzieren. Ein Kernel verwendet alle Pseudokanalschnittstellen auf der Nordseite des Chips. Der andere verwendet die Kanäle auf der Südseite.
  • Der Versuch, alle 32 Kanäle in einer einzigen 2D-FFT zu verwenden, führt zu Routing-Problemen, mit denen wir uns im Demonstrationscode nicht befassen wollten.
Jeder 2D-FFT-Kernel verbraucht etwa 30 % der DSP-Ressourcen des von uns verwendeten MX2100 FPGA.

Eine Zeile pro FPGA HBM2-Kanal

Die 2D-FFT wird mit vielen 1D-FFTs implementiert. Eine einzelne 1D-FFT sättigt den von ihr verwendeten HBM2-Kanal. Mit 16 HBM2-Kanälen verarbeitet unsere 2D-FFT-Implementierung 16 Zeilen der 1024-Zeilen-Matrix parallel. Ein High-End-GPU kann wahrscheinlich alle 1024 Zeilen in einem einzigen Durchgang verarbeiten. Der FPGA benötigt 64 Durchläufe. Die Anzahl der Durchläufe spielt jedoch keine Rolle, da die HBM2/GDDR6-Bandbreite in beiden Fällen der begrenzende Faktor ist.

400 MHz Fmax ist genug

Wir benötigen eine OpenCL-Taktfrequenz von 400 MHz, um jeden HBM2-Kanal mit den optimalen 32-Byte-Bursts zu sättigen. Schneller zu sein hat keinen Wert. Langsamer zu sein ist nicht optimal. Intels aktuelle Implementierung von DPC++ nutzt das bestehende OpenCL-Board-Support-Paket von BittWare. Daher sehen beide Implementierungen für das FPGA wie OpenCL aus. Beide Implementierungen erfordern die gleichen Optimierungen, um 400 MHz zu erreichen. Diese Anpassungen werden im Quellcode nur anders ausgedrückt.

1D-FFT-Ausgang

Die 1D-FFT gibt die Ergebnisse nicht direkt in HBM2 aus. Stattdessen schreibt sie in den internen FPGA-Speicher. Zusätzliche FPGA-Logik sammelt die Ergebnisse mehrerer 1D-FFTs, wendet diese Ergebnisse um und schreibt sie zurück in HBM2, alles parallel zur Berechnung.

1D FFT verzögerter Start

Wir starten die 16 1D-FFTs nicht im selben Taktzyklus. Stattdessen verschieben wir ihre Startpunkte um jeweils ein komplexes Element. Auf diese Weise können wir die 1D-FFT-Ergebnisse in die Corner-Turn-Logik einfließen lassen.

32-Byte Bursts

Wir müssen auf die Ausgabe von vier 1D-FFTs warten, um die transponierten Daten in einem 32-Byte-Chunk in den HBM schreiben zu können.

Einfaches Programmieren mit oneAPI

Das Entwicklungsteam von BittWare verwendet RTL (Verilog und VHDL), HLS (hauptsächlich C++), OpenCL und jetzt DPC++. Wir haben bereits ein White Paper veröffentlicht, in dem wir RTL mit HLS verglichen haben. Dieses Projekt war unsere erste Gelegenheit, OpenCL mit DPC++ zu vergleichen.

Wir freuen uns, berichten zu können, dass der Wechsel von OpenCL-Code für FPGA zu DPC++ für FPGA einfach war. Die spezifischen Anpassungen für FPGAs und den HBM2 On-Package-Speicher waren der OpenCL-Version sehr ähnlich. Die Datenbewegung auf und vom Host-Computer war einfach. Wir haben sogar unseren 2D-FFT-Kernel von NumPy aus aufgerufen, was wir mit der OpenCL-Version nie versucht haben.

Übersichtsvideo über die oneAPI für FPGA-Beschleunigung

Zusätzliche Details

Interner Speicher als Reserve

Wir verwenden 512 M20K-Speicher (12,5 % eines MX2100).

2D-FFT-Parameter

Die Länge der für FPGAs implementierten FFTs wird in der Regel bei der Kompilierung des Bitstroms festgelegt.

  1. In unserer Demonstration wird eine feste 1024 x 1024 Matrix aus komplexen 32-Bit-Gleitkommazahlen verwendet.
  2. Unsere FFT-Implementierung verschachtelt die Komponenten der komplexen Zahl (im Gegensatz zur Verwendung separater reeller und imaginärer Matrizen).
  3. Die Ausrichtung spielt keine Rolle, da die Daten in den HBM-Speicher kopiert werden, wo sie 32-Byte-ausgerichtet werden.

1D-FFT-Implementierung

Wir haben unsere eigene 1D-FFT implementiert (im Gegensatz zur Verwendung einer FPGA-IP-Bibliothek). Die 1D-FFT ist eine Radix-2-FFT und vollständig pipelined. Sie ist nicht in-place.

Leistung

Die 2D-FFT-Leistung wird immer durch die HBM2-Bandbreite begrenzt. Unser Ziel ist es daher, einen Algorithmus zu finden, mit dem wir die HBM2-Bandbreite maximieren können. Das bedeutet auch, dass wir HBM2-Bandbreiten-Benchmarks verwenden können, um die FFT-Leistung genau abzuschätzen.

Die HBM2-Spitzenleistung für eine Batch-1-Implementierung mit zwei unabhängigen Kerneln auf demselben Gerät beträgt 291 GByte/Sek. Bei Pipelining/Batching ist eine Spitzenbandbreite von 337 GByte/Sek. möglich.

Schlussfolgerung

Wir haben uns gefreut, dass wir unsere 2D-FFT schnell von einer OpenCL-Version auf oneAPI portieren konnten. Obwohl die Arbeit zur Optimierung des Ansatzes für eine HBM2-fähige FPGA-Karte bereits erledigt war, bietet sie OpenCL-basierten Anwendern einen hervorragenden Weg, um mit minimalen Auswirkungen auf oneAPI auf BittWare-Hardware umzusteigen.

Die Arbeit mit HBM2 auf FPGAs bietet bei bestimmten Anwendungen, wie wir sie hier gesehen haben, einige erhebliche Vorteile. Wenn Sie weitere Informationen zu dem von uns vorgestellten Code wünschen, setzen Sie sich bitte mit dem unten stehenden Formular in Verbindung, um die Verfügbarkeit zu erfragen oder um mehr über die 520N-MX FPGA-Karte von BittWare zu erfahren.

Anforderung des Quellcodes

Sie können die Open-Source-TAR-Datei anfordern, indem Sie dieses Formular ausfüllen. Der Code, den Sie erhalten, hat Open-Source-Legenden.

Wie man den Code verwendet:

Wir kompilieren die OneAPI 2D FFT in eine dynamisch gelinkte, gemeinsame Objektbibliothek für Linux. Geben Sie einfach "cmake ." ein, um diese Bibliothek zu erstellen.

Wir rufen diese Bibliothek über ein einfaches NumPy-Skript auf, das einige Eingabedaten erzeugt und dann die Ausgabe entweder validiert oder graphisch darstellt. Geben Sie "python runfft.py" ein, um ein Diagramm zu sehen.

Die obige Software wurde auf Centos 8 mit der Intel OneAPI-Tools Beta 10 Version unter Verwendung einer BittWare 520N-MX Karte getestet, die ein MX2100 FPGA hostet. Das veröffentlichte OpenCL-Board-Support-Paket für diese Karte ermöglicht auch die Arbeit mit OneAPI

"*" kennzeichnet Pflichtfelder

Name*
Bitte überprüfen Sie, ob diese E-Mail-Adresse aktiv ist, da die PDF-Datei über diese Adresse verschickt wird.
Adresse und Ort*