Wenn Kamerabilder zwischen zwei Boards übertragen werden, ist die Geschwindigkeit der Verbindung selten das Problem. Das Problem ist, wer das Bild transportiert. Kopiert die CPU die Daten Byte für Byte, läuft die PCIe-Verbindung mit einem Bruchteil ihrer Kapazität, und dieser Rechenkern kann nichts anderes tun. Übernimmt die DMA-Einheit im Controller die Arbeit, sagt die CPU nur noch „von hier nach dort, so viel“, den Rest erledigt die Hardware. Auf unserem Prüfstand haben wir zwischen einem TI Jacinto 7 (J784S4) und einem Jetson AGX Orin über PCIe Gen3 x4 mit DMA 3,0–3,2 GB/s gemessen; auf derselben Verbindung war DMA etwa 8-mal schneller als CPU-Kopien. Dieser Beitrag erklärt, woher dieser Unterschied kommt und welche Einstellungen ihn bestimmen.

Kurz gesagt

  • Kopiert die CPU das Bild, ist die CPU der Engpass, nicht die Leitung. Mit DMA beschreibt die CPU den Transfer nur; die Daten bewegt der Controller.
  • Die rohe Obergrenze von PCIe Gen3 x4 liegt bei 3,94 GB/s pro Richtung. Paket-Header kosten einen Teil davon; mit einer maximalen Payload von 256 statt 128 Byte steigt die Paketeffizienz von etwa 86 % auf 92 %.
  • DMA hat feste Vorbereitungskosten. Bei Transfers von wenigen Kilobyte kann die CPU-Kopie schneller sein; deshalb führt es in die Irre, aus der Bandbreite eine „Zeit pro Bild“ abzuleiten.
  • Gemessen haben wir 3,0–3,2 GB/s und etwa Faktor 8. Nicht gemessen: die Ende-zu-Ende-Latenzzeit der Linie mit vier Orins.

Der Film und die Arbeit dahinter

Unser 64-Sekunden-Film Straight to the GPU folgt einem einzelnen Bild: Es landet auf dem Jacinto, geht per PCIe in den Speicher des Orin, vier Orins übernehmen nacheinander Videostabilisierung, Bildverbesserung, Objektverfolgung und das Ablesen von Anzeigen, dann geht das Bild zurück zum Jacinto und per WebRTC auf den Bildschirm des Bedieners. Danach sieht man dieselben Boards und dasselbe Kabel, während die CPU jedes Bild kopiert.

Fabrik, Vier-Orin-Linie und Leitstand sind 3D-Illustrationen; Datenpfade und Erkennungen sind animiert. Real ist die Treiberarbeit zwischen zwei Boards und ihre Messung am Prüfstand: ein Jacinto 7 (J784S4) auf der Root-Seite, ein Jetson AGX Orin als Endpoint, dazwischen PCIe Gen3 x4. Der Betrieb des Orin als Endpoint ist ein von NVIDIA dokumentierter Modus. Den Treiber schreiben wir auf beiden Seiten. Eine Linie mit vier Orins haben wir nicht aufgebaut und nicht gemessen.

Warum wird ein Bild kopiert, und wer kopiert?

Sind zwei Boards per PCIe verbunden, gibt der Endpoint einen Teil seines Speichers als Adressfenster (BAR) für die Root-Seite frei. Der Treiber auf der Root-Seite blendet dieses Fenster in seinen Adressraum ein, und der einfachste Transfer ist ein memcpy in diese Abbildung. Das funktioniert, aber jedes Byte geht durch die CPU: Sie liest die Daten, schreibt sie in das Fenster, und der Controller macht daraus nacheinander Pakete (TLPs). Solange kopiert wird, ist der Rechenkern belegt, und die Geschwindigkeit ist die dieser Schleife, nicht die der Leitung.

Mit DMA ändert sich die Arbeitsteilung. Die CPU nennt dem Controller Quelladresse, Zieladresse und Länge; die DMA-Einheit im Controller holt die Daten aus dem Speicher und schickt sie auf die Leitung. In unserem Aufbau sitzt diese Einheit im Endpoint, also im PCIe-Controller des Orin. Der Linux-Kernel bringt für diese Art von Controller einen Treiber mit (dw-edma; im Kconfig-Text steht „normally implemented on endpoints SoCs“). Der PCIe-Controller auf der Jacinto-Seite stammt aus einer anderen IP-Familie (Cadence); anzunehmen, beide Seiten seien dieselbe Hardware, ist die erste Falle.

Die Kernel-Dokumentation benennt den Unterschied deutlich. In der Dokumentation des NVMe-Endpoint-Treibers heißt es: Wird DMA nicht unterstützt, kommt MMIO zum Einsatz, „which results in poor performance“. Im Begleitschreiben desselben Treibers werden auf einem RK3588-Board mit DMA 2,82 GB/s bei zufälligen Lesezugriffen von 512 KB berichtet. Unsere Messung stammt von anderen Boards und einer anderen Last; wir nennen den Wert, um zu zeigen, dass die Größenordnung nicht nur bei uns auftritt, nicht um die Zahlen nebeneinanderzustellen.

Wo liegt die Obergrenze der Leitung, und wie viel bleibt davon?

PCIe 3.0 überträgt 8 GT/s pro Lane und nutzt die Kodierung 128b/130b. Für vier Lanes:

4 Lanes × 8 Gbit/s × 128/130 ÷ 8 = 3,94 GB/s      (pro Richtung, roh)

Diese Grenze erreicht kein Transfer, denn die Daten werden in Pakete verpackt. Jedes Paket hat Header, Sequenznummer und Fehlerprüfung; die Xilinx-Notiz WP350 gibt diesen Overhead mit 20 bis 30 Byte an. Wie viele Daten ein Paket höchstens tragen darf (Max_Payload_Size), handeln beide Enden aus: Definiert sind 128 bis 4096 Byte, und jedes Gerät in der Hierarchie muss denselben Wert verwenden.

Max. Payload Paketeffizienz (WP350, 20 Byte Overhead) Rest von 3,94 GB/s
128 Byte 86 % etwa 3,4 GB/s
256 Byte 92 % etwa 3,6 GB/s
512 Byte 96 % etwa 3,8 GB/s

Die letzte Spalte ist unsere Multiplikation, keine Messung; bei Gen3 ist der Rahmen etwas größer als 20 Byte, und auch Flusskontrollpakete belegen die Leitung. Unsere Boards handelten beim Start 128 Byte aus; beide unterstützen 256, also haben wir den Wert erhöht. Die gemessenen 3,0–3,2 GB/s entsprechen 76–81 % der rohen Obergrenze.

Dazu kommt eine Einheitenfalle. Manche Testwerkzeuge geben 2²⁰ Byte als „MB“ aus. Im GB-Bereich macht das 7 % aus (2³⁰ / 10⁹ = 1,074); vergleichen Sie keine zwei Messungen, ohne zu wissen, welche Einheit das Werkzeug ausgibt.

Der Preis von DMA: kleine Transfers

DMA ist nicht kostenlos. Für jeden Transfer wird ein Kommando vorbereitet, Adressen werden geschrieben, am Ende kommt ein Interrupt. Diese Vorbereitung dauert eine feste Zeit, und ihr Anteil wächst, je kleiner der Transfer ist. In unseren Messungen kann die CPU-Kopie bei Transfers von wenigen Kilobyte vor DMA liegen; im Megabyte-Bereich ist DMA klar schneller.

Daraus folgen zwei praktische Dinge. Erstens die Arbeitsteilung: Steuerflags und kleine Parameter gehen per CPU, große Nutzdaten wie Bilder per DMA. Zweitens Ehrlichkeit: „3 GB/s heißt, ein 3-MB-Bild braucht 1 ms“ ist falsch, weil die feste Vorbereitungszeit ignoriert wird. Die Zeit pro Bild findet man, indem man einen Transfer dieser Größe misst, nicht indem man durch die Bandbreite teilt. Deshalb zeigt der Film keine Millisekunden.

Speichertyp: gecacht oder Write-Combining?

Wie der gemeinsame Speicher abgebildet wird, bestimmt die lokale Zugriffsgeschwindigkeit. Die Kernel-Dokumentation zu Geräte-E/A beschreibt die beiden Extreme: ioremap() umgeht den Cache und gibt jeden Zugriff einzeln an das Gerät weiter; ioremap_wc() erlaubt das Zusammenfassen von Schreibzugriffen und wird laut Dokumentation typischerweise für Video-Framebuffer verwendet, wo es die Schreibleistung erhöhen kann. Normal gecachter Speicher ist beim Lesen und Vergleichen weit schneller, unter einer Bedingung: Schreibt die Gegenseite per DMA in diesen Speicher, darf der CPU-Cache nicht mehr die alten Daten halten.

Garantiert die Hardware die Kohärenz (der Controller hängt an einer Verbindung, die mit den CPU-Caches kohärent ist), ist eine gecachte Abbildung sicher. Wenn nicht, leert man den Cache bei jedem Transfer, was CPU-Zeit kostet, oder bleibt bei Write-Combining. Wir haben auf beiden Seiten unterschiedlich entschieden: gecacht dort, wo wir die Kohärenz prüfen konnten, Write-Combining auf der anderen Seite. Die Regel ist einfach: Erst wird die Korrektheit getestet (Zufallsdaten, zufällige Adressen, Vergleich), danach die Geschwindigkeit gemessen.

Wer meldet „das Bild ist da“?

Dass ein Endpoint die Root-Seite benachrichtigt, ist Standard: Das Endpoint-Framework des Kernels bietet dafür pci_epc_raise_irq() und löst MSI oder MSI-X aus. Die Gegenrichtung ist anders. PCIe kennt keinen fertigen Interrupt-Weg, mit dem die Root-Seite einem Endpoint „es gibt neue Arbeit“ mitteilt; Linux hat eine „Doorbell“-Unterstützung in dieser Richtung erst mit Version 6.17 erhalten, und nur unter bestimmten Hardwarebedingungen. Selbst der NVMe-Endpoint-Treiber im Kernel arbeitet, indem er seine Warteschlangen ständig abfragt.

Polling kostet eines von zwei Dingen: einen Rechenkern oder Reaktionszeit. Wir verwenden Interrupts in beide Richtungen; darauf stützt sich der Satz im Film, „each one starts the moment the frame lands“. Wie das bei einer Linie mit vier Einheiten skaliert, haben wir nicht gemessen.

Was heißt „direkt in den GPU-Speicher“?

Zero-Copy bedeutet nicht, dass die Daten sich nie bewegen: Das Bild geht einmal über die Leitung. Gemeint ist, dass die CPU das Bild davor und danach nicht von einem Puffer in den nächsten kopiert. Auf dem Orin machen das zwei Dinge möglich. Der für den Transfer reservierte Speicher ist physisch fest und zusammenhängend, damit Einheiten wie die GPU denselben Bereich erreichen können. Und wie NVIDIAs Notiz „CUDA for Tegra“ festhält, liegen Gerätespeicher und Hauptspeicher bei Tegra im selben physischen DRAM, sodass doppelte Speicherzuweisungen und Datentransfers vermieden werden können.

Wie dieser Bereich auf der GPU-Seite abgebildet wird, behandelt dieser Beitrag nicht. Den Rest der Inferenz-Pipeline beschreiben wir auf unserer Seite zu NVIDIA Jetson, die Jacinto-Seite auf unserer Seite zu Texas Instruments.

Der letzte Schritt zum Bediener

Nach der Verarbeitung geht das Bild per WebRTC auf den Bildschirm des Bedieners; WebRTC ist die von W3C und IETF definierte Protokollfamilie für Echtzeitmedien im Browser. Die Verzögerung dieses Schritts ist unabhängig von PCIe: Sie hängt von der Kodierung, dem Netz und dem Puffer des Browsers ab. Die Methode beschreiben wir in unserer Notiz zu latenzarmem Video; eine Messung nennen wir hier nicht.

Wo es schiefgeht

  1. Bandbreite für Latenzzeit halten. GB/s bei einem großen Transfer sagen nichts über die Dauer eines kleinen; die feste Vorbereitungszeit dominiert.
  2. Bei der Standard-Paketgröße bleiben. Zwei Enden, die einen größeren Wert unterstützen, können beim Start trotzdem einen kleinen aushandeln. Lesen Sie den ausgehandelten Wert aus.
  3. Schnell, aber veraltet. Eine gecachte Abbildung wirkt im Vergleichstest schnell; sieht sie nicht, was die Gegenseite geschrieben hat, ist das Ergebnis falsch. Testdaten müssen zufällig sein, und der Speicher muss in jeder Runde gelöscht werden.
  4. Kollidierende reservierte Speicherbereiche. Der Transferspeicher wird im Device Tree von Hand reserviert. Überlappt er den Bereich einer anderen Einheit, warnt der Kernel nur beim Start; danach folgt stille Datenkorruption.
  5. DMA für immer schnell und immer verfügbar halten. Bei kleinen Transfers dominiert die feste Vorbereitungszeit, und nicht jede DMA-Einheit unterstützt jede Operation: Die Testanleitung des Kernels hält fest, dass der DMA-Kopiertest auf den meisten DMA-fähigen Endpoint-Controllern fehlschlägt. Messen Sie das Verhältnis auf Ihrem eigenen Board.

Was dieser Beitrag nicht sagen kann

Gemessen haben wir zwei Dinge: 3,0–3,2 GB/s zwischen zwei Boards mit DMA und etwa den Faktor 8 gegenüber CPU-Kopien bei Transfers von 128 MB. Welche der beiden Geschwindigkeiten zu welcher Richtung gehört, haben wir nicht getrennt festgehalten; deshalb nennen wir einen Bereich. Der Faktor 8 stammt aus einer früheren Messrunde und wurde mit der aktuellen DMA-Geschwindigkeit nicht erneut gemessen.

Nicht gemessen haben wir: die Ende-zu-Ende-Latenzzeit der Vier-Orin-Linie, die Zeit eines Bildes von der Kamera bis zum Bediener, die Interrupt-Latenz unter Last und die Stabilität im Dauerbetrieb. Für eine Antwort würden wir messen:

  • Transferzeit in Bildgröße: nicht den Mittelwert, sondern p99 und den schlechtesten Wert, mit realen Bildgrößen.
  • Zeit vom Interrupt bis zur Arbeit: vom Eintreffen des Bildes bis zum Start des GPU-Jobs, mit Hardware-Zeitstempeln.
  • Die Summe der Kette: wie die Verzögerung mit der Zahl der Einheiten wächst.
  • Glass-to-Glass-Latenz: vom Ereignis vor der Kamera bis zum Pixel auf dem Bildschirm des Bedieners.

Eine solche Linie auf Ihren eigenen Boards aufzubauen, ist die Treiberschicht einer Edge-AI-Pipeline.

Häufig gestellte Fragen

Was bedeutet Zero-Copy bei PCIe?

Das Bild geht einmal über die Leitung zwischen zwei Boards, und die CPU kopiert es davor und danach nicht von einem Puffer in den nächsten. Die DMA-Einheit des Controllers bewegt die Daten; die CPU beschreibt nur den Transfer.

Wie viele Daten überträgt eine PCIe-Gen3-x4-Verbindung höchstens?

Die rohe Obergrenze liegt bei 3,94 GB/s pro Richtung (4 Lanes × 8 Gbit/s × 128/130). Paket-Header und Flusskontrolle kosten einen Teil davon; der Verlust sinkt mit größerer maximaler Payload. Auf unserem Prüfstand haben wir mit DMA 3,0–3,2 GB/s gemessen.

Ist DMA immer schneller als eine CPU-Kopie?

Nein. DMA hat bei jedem Transfer feste Vorbereitungskosten; bei wenigen Kilobyte kann die CPU-Kopie schneller sein. Im Megabyte-Bereich ist DMA klar schneller: auf unserer Verbindung etwa Faktor 8 bei Transfers von 128 MB.

Lässt sich die Latenzzeit pro Bild aus der Bandbreite berechnen?

Das sollte man nicht tun. Die Division ignoriert die feste Vorbereitungszeit, die Interrupt-Latenz und die übrigen Schritte der Kette. Ein Transfer in Bildgröße muss direkt gemessen werden.

Quellen

Abgerufen am 1. Oktober 2026.