Warum gelten Felder mit Längenpräfixen als hardwareunfreundlich?

Ein Kritikpunkt an GENEVE (einem Netzwerk-Kapselungsprotokoll) ist, dass es Tag-Längen-Wert-Felder verwendet, die in Hardware schwer zu verarbeiten sind.

Warum wird dies als Hardware-unfreundlich angesehen? Welche Ansätze wären für die Implementierung von Hochgeschwindigkeitshardware geeigneter und warum?

Antworten (2)

Tag (oder Typ)-Länge-Wert (TLV) ist eine Methode, um verschiedene Arten von Informationen variabler Länge in einer Datenstruktur aufzunehmen.

Sie brauchen das nur, wenn es keine gemeinsame Teilmenge von Informationen gibt, die jede Instanz dieser Datenstruktur haben muss, oder wenn die Reihenfolge der Felder aus irgendeinem Grund variabel sein muss .

Stellen Sie sich das so vor: Wenn alle GENEVE-Pakete ein "Ziel"-Feld hätten, das beispielsweise eine 64-Bit-Netzwerkadresse enthielt, warum definieren Sie dann nicht einfach, dass jedes Paket mit einer 64-Bit-Zieladresse beginnt, und sparen sich ein Tag und ein Längenfeld?

Hardware (und dazu gehört auch Hardware, auf der Software läuft!) ist gut darin, Werte an bestimmten Positionen nachzuschlagen. Das Parsen eines Headers, bei dem sich die Zieladresse immer an Position x befindet und immer die Länge y hat, ist sehr einfach. Sie lesen einfach die Speicheradresse x und interpretieren das Ergebnis als Ganzzahl der Länge y. Das tun zB CPUs für alles, was sie aus dem RAM lesen.

Wenn Sie andererseits ein Paket verstehen möchten, müssen Sie zuerst nach bestimmten Feldern suchen , indem Sie TLV-Felder durchlaufen (ok, das erste Feld sagt, dass es nicht das Tag ist, nach dem ich suche, es hat eine Länge von 14, also springen Sie 14 Bit weiter , aha, nicht das Feld, nach dem ich suche, springen Sie vor, ...), dann wird das Parsen dieses Pakets langsam sein. Das gilt für Software genauso wie für Hardware-Implementierungen.

Noch schlimmer als langsam, es wird in seiner Komplexität nicht deterministisch sein. Einige TLV-Strukturen benötigen also möglicherweise nur einen einzigen Taktzyklus zur Analyse, andere müssen 42 Felder durchlaufen, um dasselbe zu tun. Wenn Sie eine Signalverarbeitungsanwendung implementieren, wird die Berücksichtigung zufälliger Verzögerungen in einem der Schritte schnell zu einem Albtraum, da Sie plötzlich Eingaben puffern, Gegendruck anwenden oder Daten löschen müssen, nur weil sich jemand für eine flexible Datenstruktur entschieden hat .

In der Software ist es oft billig und relativ schnell, einfach eine Header-Struktur mit festen Offsets vorab zuzuweisen und diese Felder "auszufüllen", während Sie die eingehende TLV-Struktur durchlaufen. Aber: Dafür braucht man RAM, und oft ziemlich viel RAM, wenn man nicht wissen kann, welche Felder man sucht, wenn man anfängt, die Struktur zu parsen.

TLV ist also ein gängiges Schema zur Serialisierung schwach strukturierter Daten zur dauerhaften Speicherung oder langsamen Übertragung. Es ist normalerweise ziemlich unerwünscht für Streaming-Anwendungen, wo ziemlich oft die gleiche Art von Daten ankommt (z. B. Netzwerkpakete, Videoframes, Infrastrukturbetriebsbefehle…); dann definierst du lieber feste Strukturen vor, auch wenn dadurch etwas Transportbandbreite für gelegentlich ungenutzte Felder verschwendet wird.

Beispielsweise verwenden die meisten Systeme nicht alle Felder, die ein Ethernet-Paket haben kann. Zwei Bytes würden Sie trotzdem nicht versuchen einzusparen – 1490 oder 1492 Bytes im Gigabit-Ethernet zu transportieren, macht keinen großen Unterschied, aber bei jedem einzelnen Paket prüfen zu müssen, ob Ihr Paket vom Typ A oder vom Typ B ist, wirkt sich negativ aus.


@Janka spricht einen wichtigen Punkt an: Angenommen, die gesamte Aufgabe Ihrer Hardware besteht nur darin, das gesamte Paket von der Ein- zur Ausgabe zu kopieren. Nun, großartig, anstatt Ihrer DMA-Engine zu sagen, dass sie Daten im Wert von einem Paket vom Eingang zum Ausgang kopieren soll, parsen Sie alle Eingaben, um herauszufinden, wie lang Ihre Daten sind. Das ist viel, viel langsamer als nur das Kopieren von Daten.

+1, aber die sehr kurze Antwort lautet: DMA wird die Daten nicht analysieren, daher bewirken Längenfelder nichts anderes, als Overhead hinzuzufügen.
Nun, @Janka, ja, das ist die Kurzform von "wo andere nur eine feste Position und Länge von Daten auswählen können, muss der TLV-Benutzer zuerst die vollständige Struktur analysieren".
Das ist alles richtig, aber im Vergleich zu fast jedem anderen Muster, das Daten mit variabler Länge oder optionalen Daten zulässt, ist TLV effizient, einfach zu verarbeiten und erlaubt zukünftige Erweiterungen. Auf einer Skala von Ethernet-Headern zu SQL bis „Datum auf einem Erneuerungsaufkleber auf einem Nummernschild, aufgenommen in einem Überwachungsvideo“ landet TLV viel näher am effizienteren/maschinenfreundlicheren Ende der Datenübertragung.
Das einzige TLV, das ich kenne, ist Zeug wie Gzip oder eine variable Komprimierungsdatei. Nicht dasselbe wie normale Daten oder sogar verschlüsselte Daten.
@Ben hat natürlich recht! Wenn Sie optionale Daten haben, können Sie nicht viel dagegen tun, außer sie am Ende Ihrer Pflichtfelder als tlv zu haben. Der Punkt ist, dass Sie überlegen müssen, was obligatorisch ist und was nicht.
@ Sparky256: ASN.1 BER/CER/DER verwenden alle TLV (es ist kein "reines" TLV, da ein Tag einen Datensatz einführen kann, der mehrere Felder enthält, die nicht einzeln gekennzeichnet sind) und ist in Netzwerkprotokollen äußerst weit verbreitet.
Absolut! Aber: Wenn Ihr Paket hauptsächlich aus einem Feld besteht, wird das Tag dieses Felds effektiv zu "Pakettyp"; Wenn dieser Pakettyp dann eine feste Datensatzstruktur einführt, treten die von mir beschriebenen Probleme nicht auf.
@MarcusMüller: Nun, in ASN.1 haben einige Daten eine feste Datensatzstruktur und minimieren eingebettete Tags in einigen Kodierungen, aber es gibt auch eine Menge Verwendung von Vereinigungen, und jedes Mal, wenn eine Vereinigung oder eine Folge davon erscheint, erhalten Sie mehr TLV. Und andere der Codierungen markieren alles.

Zusätzlich zu der großartigen Antwort von Marcus möchte ich hinzufügen, dass Felder mit vorangestellter Länge oft als minderwertig gegenüber terminierten Feldern angesehen werden, da sie einen zusätzlichen Zähler für die Verarbeitung benötigen.

Das klassische Beispiel sind C-Saiten. Es ist nur ein einziger Zeiger erforderlich, um eine Zeichenfolge zu verarbeiten, da Sie den Zeiger einfach weiter inkrementieren, bis Sie das Null-Terminierungszeichen erreichen. Mit einem Längenpräfix benötigen Sie einen zusätzlichen Zähler, um zu verfolgen, wie viele Zeichen Sie verarbeitet haben, was mehr Speicher und mehr Verarbeitungsaufwand bedeutet, um ihn weiter zu erhöhen.

Es mag wie eine Kleinigkeit erscheinen, aber auf Systemen mit sehr geringem Stromverbrauch oder niedrigen Kosten oder niedrigen Spezifikationen ist es wichtig.

OTOH, Code, der C-Strings verarbeitet, muss den String oft einmal scannen, um die Länge zu finden, und dann erneut, um ihn zu verarbeiten. Du gewinnst etwas, du verlierst etwas.
Das ist der andere Teil des Designs, der sorgfältig überlegt werden muss, um dies zu vermeiden.