diff --git a/FrOSCon26/FrOSCon.26.mm b/FrOSCon26/FrOSCon.26.mm index 5333c37..3ccbff1 100644 --- a/FrOSCon26/FrOSCon.26.mm +++ b/FrOSCon26/FrOSCon.26.mm @@ -309,6 +309,14 @@ + + + + + + + + @@ -440,16 +448,428 @@ + + + + + + + + +

+ AsyncIO für sehr hohen throughput +

+ + +
+ + + + + +

+ also ehr im Bereich von Millionen Requests / sec +

+ + +
+ + + + + + + + + +

+ deshalb war die Behandlung von Files stets etwas asymetrisch. Auch wenn der Socket ready ist, kann er dann doch noch blocken, wenn das System unter Druck steht. +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ man kann auch mehrere Einträge hinzufügen und dann antriggern +

+ + +
+
+ + + + + + +

+ dann erkennt der Kernel sebständig, wenn was neues in der Queue ist +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +

+ ....vermutlich wird der Buffer-Speicher einfach geeignet auch in den Kernel-Space gemapped; jedoch das Setup mit den Command/Completion-Ringbuffern isoliert den User komplett von diesen Fragen. Sehr geschickt! +

+ + +
+ +
+
+
+ + + + + + + + + + + + +
struct iovec {
+     void  *iov_base;    /* Starting address */
+     size_t iov_len;     /* Number of bytes to transfer */
+};
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Im Submission-Ringbuffer liegt nur eine Index-Nummer, die in ein daneben stehendes weiteres Array zeigt. Im Tutorial heißt es, das sei so konstruiert worden, um Applikationen zusätzliche Flexibilität zu geben (was ich nicht wirklich verstehe, da ja auch das externe SQ-Array im mmapped-mem liegen muß) +

+ + +
+
+
+ + + + + + + + +

+ damit man zu Beginn die neuesten Updates vom Kernel mitbekommt, und am Ende dem Kernel die neue Schreib/Lese-Position sichtbar gemacht wird +

+ + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + +

+ im Tutorial-Beispiel: io_uring_prep_readv() füllt einen SQ-Entry passend aus für eine readv-Operation +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ weil der Buffer shared in den Client-Process-Space gemapped ist, muß der Kernel keine Daten mehr explizit in den Ziepuffer im Prozeß kopieren +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + +

+ ...also eine kleine State-machine implementieren: Completion-Entries entgegennehmen, schauen ob komplett und partiell, partielle nochmal auf den Weg schicken, Komplette am Buffer markieren. Danach würde die Render-Aktion laufen, und lediglich schauen, ob die Daten in »ihrem« Buffer schon da sind. Alles per Modulus gesteuert. +

+ + +
+
+ + + + + + +

+ der sollte dann die gleiche Größe haben wie der Kernel-Ringbuffer; man würde damit einen Task sofort in den passenden Buffer-Slot schicken +

+ +
+
+ + + + + + +

+ Damit das funktioniert, muß sich das System selbst beobachten: einen EMA für den IO-Vorlauf; entsprechend viele Zyklen vorher eine neue IO-Aktion auf den Weg schicken. +

+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +

+ In der Chase-Phase werden blank-Frames ausgegeben, solange bis wir Frames mit genügend Vorlauf im Speicher haben. Danach, in der Lock-Phase ist eine Relation zwischen der rotierenden Buffer-Position und dem aktuellen Flip gesetzt. Ab dem Punkt kann man N Frames im Voraus die IO-Aktion losschicken. +

+ + +
+
+ + + + + + +

+ Zu Beginn schicken wir M Frames auf den Weg; die brauchen u.U länger. Schön wäre es natürlich, wenn man diesen Selbs-regulierenden Mechanismus auch live zeigen könnte +

+ + +
+
+
+
+
@@ -1779,9 +2199,13 @@ - - + + + + + +