In das Thema IO-URING eingelesen
This commit is contained in:
parent
00e8460d1c
commit
10f155d1a3
1 changed files with 428 additions and 4 deletions
|
|
@ -309,6 +309,14 @@
|
|||
<node CREATED="1779396306814" ID="ID_1325281102" LINK="https://en.wikipedia.org/wiki/Io_uring" MODIFIED="1779396315914" TEXT="Wikipedia">
|
||||
<node CREATED="1779397158957" ID="ID_635788695" LINK="https://web.archive.org/web/20251010072644/https://kernel.dk/io_uring.pdf" MODIFIED="1779397176550" TEXT="verlinkt auf Einführungs-Artikel: »Efficient IO with io_uring«"/>
|
||||
<node CREATED="1779397215245" ID="ID_533486044" LINK="https://lwn.net/Articles/810414/" MODIFIED="1779397234502" TEXT="LWN: rapid growth of io_uring (2020)"/>
|
||||
<node CREATED="1783367993803" ID="ID_1431968418" LINK="https://towardsdev.com/io-uring-vs-epoll-syscall-overhead-linux-performance-a3d7fcc6c9b9?gi=3c0154f883b2" MODIFIED="1783368130857" TEXT="Medium.com: The Linux I/O Interface That Finally Makes Sense">
|
||||
<node CREATED="1783368130854" ID="ID_478257500" LINK="https://web.archive.org/web/20260706200044/https://towardsdev.com/io-uring-vs-epoll-syscall-overhead-linux-performance-a3d7fcc6c9b9?gi=da9a38a5a4e5" MODIFIED="1783368133389" TEXT="A"/>
|
||||
</node>
|
||||
<node CREATED="1783368328751" ID="ID_1994767905" LINK="https://unixism.net/2020/04/io-uring-by-example-article-series/" MODIFIED="1783368342820" TEXT="IO_URING by example (2020)">
|
||||
<node CREATED="1783368348940" ID="ID_888420188" LINK="https://github.com/shuveb/io_uring-by-example" MODIFIED="1783368354081" TEXT="zugehöriger Github"/>
|
||||
</node>
|
||||
<node CREATED="1783370353779" ID="ID_72316824" LINK="https://www.reddit.com/answers/f06c7939-9e61-4d8b-96a0-45180c7ef398/?q=%C3%9Cberblick+io_uring+in+Linux&source=PDP" MODIFIED="1783370359891" TEXT="Reddit-Übersichtsseite"/>
|
||||
<node CREATED="1783370514114" ID="ID_1349175602" LINK="https://arxiv.org/abs/2512.04859" MODIFIED="1783370550553" TEXT="Interessant: arXiv — High-Performance DBMSs with io_uring: When and How to use it"/>
|
||||
</node>
|
||||
<node CREATED="1779399048372" ID="ID_1376049416" LINK="https://unixism.net/loti/" MODIFIED="1779399068596" TEXT="»Lord of the uring«"/>
|
||||
</node>
|
||||
|
|
@ -440,16 +448,428 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783380531260" ID="ID_469108654" MODIFIED="1783380548076" TEXT="mit dem Thema vertraut machen....">
|
||||
<node CREATED="1783380549407" ID="ID_1386950252" MODIFIED="1783380553917" TEXT="grundsätzich">
|
||||
<node CREATED="1783380554930" ID="ID_840014622" MODIFIED="1783380581481">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
AsyncIO für <i>sehr hohen</i> throughput
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
also ehr im Bereich von Millionen Requests / sec
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1783380657844" ID="ID_1057905414" MODIFIED="1783380667920" TEXT="erst da macht sich der Kontext-Switch bemerkbar"/>
|
||||
<node CREATED="1783380668713" ID="ID_1392613640" MODIFIED="1783380678765" TEXT="für tausende Requests/sec reicht ein Threadpool"/>
|
||||
</node>
|
||||
<node CREATED="1783380582620" ID="ID_188672487" MODIFIED="1783380656505" TEXT="aber: Files sind immer "ready" und ePoll meldet nur das">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
deshalb war die Behandlung von Files stets etwas asymetrisch. Auch wenn der Socket <i>ready</i> ist, kann er dann doch noch blocken, wenn das System unter Druck steht.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783380681615" ID="ID_849345355" MODIFIED="1783380696024" TEXT="das ist für uns das zentrale Argument">
|
||||
<icon BUILTIN="back"/>
|
||||
</node>
|
||||
<node CREATED="1783382094070" ID="ID_434911517" MODIFIED="1783382108385" TEXT="außerdem: AIO erlaubt nur direktes, unbuffered IO"/>
|
||||
</node>
|
||||
<node CREATED="1783380898163" ID="ID_504375047" MODIFIED="1783380914611" TEXT="Struktur des io_uring-Interface">
|
||||
<node CREATED="1783381938828" ID="ID_651806818" MODIFIED="1783381950696" TEXT="Lord-of-the-uring-Tutorial">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1783380936792" ID="ID_1455615031" MODIFIED="1783380942073" TEXT="zwei Ringbuffer-Kanäle">
|
||||
<node CREATED="1783380943213" ID="ID_1918214029" MODIFIED="1783380969821" TEXT="SQ = submission queue"/>
|
||||
<node CREATED="1783380958402" ID="ID_371171829" MODIFIED="1783380967381" TEXT="CQ = completion queue"/>
|
||||
<node CREATED="1783380992795" ID="ID_1515222220" MODIFIED="1783381004376" TEXT="Speicher für die Ringbuffer is shared (user/kernel space)"/>
|
||||
<node CREATED="1783381017807" ID="ID_552310788" MODIFIED="1783381022222" TEXT="einrichten">
|
||||
<node CREATED="1783381034591" ID="ID_1237271759" LINK="https://unixism.net/loti/ref-iouring/io_uring_setup.html#c.io_uring_setup" MODIFIED="1783381043083" TEXT=" io_uring_setup()">
|
||||
<node CREATED="1783387356135" ID="ID_1660238093" MODIFIED="1783387385016" TEXT="die Länge des Queue-Ringbuffers kann man konfigurieren"/>
|
||||
</node>
|
||||
<node CREATED="1783381048487" ID="ID_384071147" MODIFIED="1783381055553" TEXT="dann per mmap in den user-space mappen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783381397970" ID="ID_1269361958" MODIFIED="1783381400665" TEXT="Verwenden...">
|
||||
<node CREATED="1783381413665" ID="ID_738123625" MODIFIED="1783381418189" TEXT="add submission queue entry"/>
|
||||
<node CREATED="1783381440513" ID="ID_1540836016" LINK="https://unixism.net/loti/ref-iouring/io_uring_enter.html#c.io_uring_enter" MODIFIED="1783381479636" TEXT="io_uring_enter()">
|
||||
<node CREATED="1783381449741" ID="ID_1923740843" MODIFIED="1783381497303" TEXT="triggert den Kernel an: neue SQE da">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
man kann auch mehrere Einträge hinzufügen und dann antriggern
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783381503670" ID="ID_176407271" LINK="https://unixism.net/loti/tutorial/sq_poll.html#sq-poll" MODIFIED="1783381536644" TEXT="oder Submisssion-Queue-Polling verwenden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
dann erkennt der Kernel sebständig, wenn was neues in der Queue ist
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783381563444" ID="ID_1738464780" MODIFIED="1783381590147" TEXT="kann auch warten bis eine gewisse Zahl an CQ Entries zurückgeschickt wurde"/>
|
||||
</node>
|
||||
<node CREATED="1783381611534" ID="ID_1396608178" MODIFIED="1783381625024" TEXT="ein CQE pro SQE, mit Ergebnis-Status">
|
||||
<node CREATED="1783387631984" ID="ID_888714962" MODIFIED="1783387642585" TEXT="werden verbunden durch einen user_data-Pointer"/>
|
||||
<node CREATED="1783387674355" ID="ID_1734790893" MODIFIED="1783387688094" TEXT="dieser wird vom Kernel einfach unverändert durchgereicht"/>
|
||||
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1783389920263" ID="ID_631311167" MODIFIED="1783389939307" TEXT="Ha! das paßt perfekt auf mein Design der Continuations im Scheduler">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783384996718" ID="ID_1183383765" MODIFIED="1783385010780" TEXT="CQ-Entries kommen in beliebiger Reihenfolge (wenn ready)">
|
||||
<node CREATED="1783385011889" ID="ID_141657481" MODIFIED="1783385016940" TEXT="man kann aber Ordnung erzwingen"/>
|
||||
</node>
|
||||
<node CREATED="1783390082574" ID="ID_693582801" MODIFIED="1783390088426" TEXT="Daten / Buffer">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1783390090337" ID="ID_1527986562" MODIFIED="1783390107574" TEXT="hier überträgt sich die Systematik der alten IO-Syscalls"/>
|
||||
<node CREATED="1783390108838" ID="ID_1250332278" MODIFIED="1783390117912" TEXT="man gibt einen Buffer im User-Process-Space an"/>
|
||||
<node CREATED="1783390118846" ID="ID_752139916" MODIFIED="1783390138958" TEXT="der Kernel sorgt dafür, daß dort die Daten landen"/>
|
||||
<node CREATED="1783390139733" ID="ID_1637000405" MODIFIED="1783390228531" TEXT="wie er das macht, kann uns egal sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
....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!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783381920148" ID="ID_1220852513" MODIFIED="1783381925793" TEXT="low-level-Interface">
|
||||
<node CREATED="1783381965202" ID="ID_1728181714" MODIFIED="1783381975125" TEXT="Tutorial: erst einmal redv() verstehen...">
|
||||
<node CREATED="1783382282094" ID="ID_1820629134" MODIFIED="1783446293619" TEXT="scatter/gather-IO bzw. vectored IO">
|
||||
<linktarget COLOR="#fdfdca" DESTINATION="ID_1820629134" ENDARROW="Default" ENDINCLINATION="1190;0;" ID="Arrow_ID_836559053" SOURCE="ID_668632489" STARTARROW="None" STARTINCLINATION="619;22;"/>
|
||||
</node>
|
||||
<node CREATED="1783382409880" ID="ID_1027835294" MODIFIED="1783382419498" TEXT="bekommt eine Liste von Auftrags-Structs">
|
||||
<node CREATED="1783382430363" ID="ID_1171141321" MODIFIED="1783382439848" TEXT="struct iovec">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<pre http-equiv="content-type" content="text/html; charset=utf-8" class="enlighter-clipboard">struct iovec {
|
||||
void *iov_base; /* Starting address */
|
||||
size_t iov_len; /* Number of bytes to transfer */
|
||||
};</pre>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783384437400" ID="ID_261205380" MODIFIED="1783384460053" TEXT="transferiert den File-content lückenlos der Reihe nach in die Buffer"/>
|
||||
</node>
|
||||
<node CREATED="1783387732857" ID="ID_1688041268" MODIFIED="1783387775312" TEXT="CQE hat user_date, res/error-code, wie read()"/>
|
||||
<node CREATED="1783387816253" ID="ID_480695787" MODIFIED="1783387823986" TEXT="SQE ist eine Command-struct">
|
||||
<node CREATED="1783387824860" ID="ID_1367724603" MODIFIED="1783387827979" TEXT="hat eine Command-ID"/>
|
||||
<node CREATED="1783387828460" ID="ID_854431460" MODIFIED="1783387836666" TEXT="und dann diverse multi-purpose-fields"/>
|
||||
<node CREATED="1783387924878" ID="ID_1554669393" MODIFIED="1783387936427" TEXT="Aufrufe sind modelliert nach bekannten IO-Operationen">
|
||||
<node CREATED="1783388108773" ID="ID_1963002363" MODIFIED="1783388118801" TEXT="bsp: verwendet einen File-Descriptor"/>
|
||||
<node CREATED="1783388119281" ID="ID_595160605" MODIFIED="1783388126033" TEXT="hat einen Offset in das File"/>
|
||||
<node CREATED="1783388126544" ID="ID_1557501628" MODIFIED="1783388139315" TEXT="bekommt einen Buffer-pointer oder einen iovec"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783388781316" ID="ID_1265251773" MODIFIED="1783388814792" TEXT="man gibt eine struct io_uring_params an den io_uring_setup()"/>
|
||||
<node CREATED="1783388646919" ID="ID_1468403550" MODIFIED="1783388660393" TEXT="man definiert sich selbst passende Schnittstellen-Structs">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783388674071" ID="ID_1871456691" MODIFIED="1783439712989" TEXT="Frage: warum ist das nicht vom Kernel vordefiniert?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1783388990307" ID="ID_1963229698" MODIFIED="1783389000855" TEXT="weil das schon ein Abstraktionslayer ist"/>
|
||||
<node CREATED="1783389001425" ID="ID_149275964" MODIFIED="1783389017213" TEXT="der Kernel definiert lediglich die Basis-structs SQE und CQE"/>
|
||||
<node CREATED="1783389033526" ID="ID_531781879" MODIFIED="1783389070406" TEXT="die Positionen der Ringbuffer-Kontrollfelder sind quasi-dynamisch"/>
|
||||
<node CREATED="1783389073434" ID="ID_378448165" MODIFIED="1783389087003" TEXT="sie werden per io_uring_params zurückgegeben"/>
|
||||
<node CREATED="1783389088143" ID="ID_1057767628" MODIFIED="1783389106739" TEXT="deshalb ist es sinnvoll, sich da eine Interface-struct drüberzusetzen"/>
|
||||
</node>
|
||||
<node CREATED="1783388687235" ID="ID_572599133" MODIFIED="1783388699931" TEXT="diese kann man dann per mmap in den user-space mappen"/>
|
||||
<node CREATED="1783388891850" ID="ID_54309322" MODIFIED="1783388907891" TEXT="für das zu mappende "file" gibt es einen File-Descriptor"/>
|
||||
<node CREATED="1783388921357" ID="ID_788864531" MODIFIED="1783388932860" TEXT="dieser wird von io_uring_setup() zurückgeliefert"/>
|
||||
</node>
|
||||
<node CREATED="1783439723372" ID="ID_70450003" MODIFIED="1783439731172" TEXT="Ringbuffer sind auf Index-Basis implementiert">
|
||||
<node CREATED="1783439735880" ID="ID_1310555659" MODIFIED="1783439754513" TEXT="es ist ein Array, wobei head und tail als Indices gegeben sind"/>
|
||||
<node CREATED="1783439755001" ID="ID_339978399" MODIFIED="1783439785005" TEXT="vor dem Zugriff wird der Index modulo die Ringbuffer-Länge genommen"/>
|
||||
<node CREATED="1783439788873" ID="ID_800063940" MODIFIED="1783439821495" TEXT="Kontrollfelder und die Entry-Arrays liegen im shraed (mmaped) memory"/>
|
||||
<node CREATED="1783439823932" ID="ID_51197608" MODIFIED="1783439987223" TEXT="die SQ-Entries werden über eine weitere Indirektion mitgeteilt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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ß)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783439999125" ID="ID_1383082691" MODIFIED="1783440018308" TEXT="Sichtbarkeit über Thread-Grenzen beachten">
|
||||
<node CREATED="1783440021146" ID="ID_171647218" MODIFIED="1783440029669" TEXT="shared-memory-Programmierung..."/>
|
||||
<node CREATED="1783440030756" ID="ID_1601251687" MODIFIED="1783440088278" TEXT="braucht immer eine Read-barrier und am Ende eine write-barrier">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
damit man zu Beginn die neuesten Updates vom Kernel mitbekommt, und am Ende dem Kernel die neue Schreib/Lese-Position sichtbar gemacht wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783440089704" ID="ID_1425651981" MODIFIED="1783440102635" TEXT="das genügt hier, da es sich um single-Producer/Consumer handelt"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783440114398" ID="ID_1217216266" MODIFIED="1783440119000" TEXT="liburing verwenden">
|
||||
<node CREATED="1783440833117" ID="ID_839873138" MODIFIED="1783440844539" TEXT="stellt ein C-Interface für den Zugriff auf die Ringbuffer bereit">
|
||||
<node CREATED="1783440926298" ID="ID_170963361" MODIFIED="1783440944465" TEXT="eine Schnittstellen-struct io_uring">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783440846153" ID="ID_1052852486" MODIFIED="1783440859478" TEXT="man kann...">
|
||||
<node CREATED="1783440860347" ID="ID_134839902" MODIFIED="1783440877595" TEXT="auf den nächsten CQ-Entry blockend warten"/>
|
||||
</node>
|
||||
<node CREATED="1783440882234" ID="ID_301034439" MODIFIED="1783440900525" TEXT="die read/write-Barrieren sind verborgen">
|
||||
<node CREATED="1783440901646" ID="ID_1734627767" MODIFIED="1783440912071" TEXT="stattdessen: io_uring_cqe_seen"/>
|
||||
<node CREATED="1783442225762" ID="ID_1142061633" MODIFIED="1783442228423" TEXT="io_uring_submit(ring)"/>
|
||||
</node>
|
||||
<node CREATED="1783442066344" ID="ID_345729175" MODIFIED="1783442157624" TEXT="stellt high-level parameter-Konstruktoren für die Operationen bereit">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
im Tutorial-Beispiel: io_uring_prep_readv() füllt einen SQ-Entry passend aus für eine readv-Operation
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783446631153" ID="ID_235240398" LINK="https://unixism.net/2020/04/io-uring-by-example-part-2-queuing-multiple-requests/" MODIFIED="1783446637597" TEXT="Tutorial: async coply">
|
||||
<node CREATED="1783446647749" ID="ID_1584749060" MODIFIED="1783446656535" TEXT="alloziert jeweils eine Buffer + einen descriptor"/>
|
||||
<node CREATED="1783446657178" ID="ID_42171709" MODIFIED="1783446665185" TEXT="hängt diese als user-data an den Request"/>
|
||||
<node CREATED="1783446669249" ID="ID_1943056546" MODIFIED="1783446680844" TEXT="macht die Queue erst mit read-requests voll"/>
|
||||
<node CREATED="1783446681440" ID="ID_1130661279" MODIFIED="1783446690677" TEXT="im descriptor gibt es eine read/write-flag"/>
|
||||
<node CREATED="1783446691449" ID="ID_557522221" MODIFIED="1783446702668" TEXT="damit wird ein copy-Prozeß realisiert"/>
|
||||
<node CREATED="1783446913957" ID="ID_457406046" MODIFIED="1783446917117" TEXT="Komplikationen">
|
||||
<node CREATED="1783446918040" ID="ID_742805192" MODIFIED="1783447636257" TEXT="anscheinend gibt es einen "retry", signalisiert mit EAGAIN">
|
||||
<node CREATED="1783447637802" ID="ID_1480100399" MODIFIED="1783447653363" TEXT="readv() ist nur eine scatter/gather-variante von read/write()"/>
|
||||
<node CREATED="1783447770285" ID="ID_1587286955" MODIFIED="1783447818026" TEXT="wenn man read() mit Flag O_NONBLOCK aufruft, könnte der physiche Read trotzdem blocken"/>
|
||||
<node CREATED="1783447818970" ID="ID_1745751924" MODIFIED="1783447840404" TEXT="in diesem Fall liefert read() einen Fehler (ret=-1) mit Errno == EAGAIN"/>
|
||||
</node>
|
||||
<node CREATED="1783446948271" ID="ID_75609256" MODIFIED="1783446958635" TEXT="außerdem können reads/writes kürzer sein als instruiert">
|
||||
<node CREATED="1783447857789" ID="ID_1707492290" MODIFIED="1783447870607" TEXT="das ist explizit so vorgesehen"/>
|
||||
<node CREATED="1783447871203" ID="ID_1408811228" MODIFIED="1783447879544" TEXT="kann sein, daß das File zuende ist"/>
|
||||
<node CREATED="1783447880121" ID="ID_1382932735" MODIFIED="1783447896011" TEXT="kann aber auch durch einen Interrupt bewirkt sein"/>
|
||||
</node>
|
||||
<node CREATED="1783446959217" ID="ID_1108500089" MODIFIED="1783446972605" TEXT="in beiden Fällen muß man einen Request anpassen / nochmal senden"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783467860105" ID="ID_562346346" MODIFIED="1783467875236" TEXT="spezielle Aspekte">
|
||||
<node CREATED="1783467876349" ID="ID_76451018" LINK="https://unixism.net/loti/tutorial/sq_poll.html#sq-poll" MODIFIED="1783468042036" TEXT="submission-polling">
|
||||
<node CREATED="1783467887910" ID="ID_663414334" MODIFIED="1783467904503" TEXT="der Kernel erkennt neue Submission-Queue-Entries von selbst"/>
|
||||
<node CREATED="1783467913708" ID="ID_1956703105" MODIFIED="1783467937206" TEXT="das spart einen Syscall pro Batch"/>
|
||||
<node CREATED="1783468073102" ID="ID_1192604598" MODIFIED="1783468079770" TEXT="aktiviert per Flag beim Setup">
|
||||
<node CREATED="1783468234883" ID="ID_422059492" MODIFIED="1783468250144" TEXT="außerdem: muß das "fixed-files"-feature verwenden"/>
|
||||
<node CREATED="1783468250631" ID="ID_229494074" MODIFIED="1783468266874" TEXT="das ist ein vorbereitetes Array mit File-Descriptoren"/>
|
||||
</node>
|
||||
<node CREATED="1783467937700" ID="ID_1422805249" MODIFIED="1783467948389" TEXT="ABER: Kernel verwendet einen poller-Thread">
|
||||
<node CREATED="1783467954732" ID="ID_161296285" MODIFIED="1783467979900" TEXT="der verursacht eine nicht-triviale CPU-Last"/>
|
||||
<node CREATED="1783467981270" ID="ID_1932680351" MODIFIED="1783467997361" TEXT="und er endet von selber, wenn idle; muß dann neu gestartet werden"/>
|
||||
</node>
|
||||
<node CREATED="1783468009859" ID="ID_37458969" MODIFIED="1783468021842" TEXT="also ⟹ trade-off"/>
|
||||
</node>
|
||||
<node CREATED="1783471315936" ID="ID_238162094" MODIFIED="1783471325172" TEXT="Completions entnehmen">
|
||||
<node CREATED="1783471326168" ID="ID_1768891087" MODIFIED="1783471336770" TEXT="es gibt einen blocking poll"/>
|
||||
<node CREATED="1783471337414" ID="ID_1463733161" MODIFIED="1783471345321" TEXT="man kann aber peek-Funktionen verwenden"/>
|
||||
<node CREATED="1783471346034" ID="ID_821102680" MODIFIED="1783471359503" TEXT="das geht auch für einen Batch von Entries"/>
|
||||
</node>
|
||||
<node CREATED="1783469960153" ID="ID_1792704761" LINK="https://unixism.net/loti/tutorial/link_liburing.html#link-liburing" MODIFIED="1783471296410" TEXT="man kann Jobs sequentiell verketten">
|
||||
<node CREATED="1783469982826" ID="ID_1031698216" MODIFIED="1783469991377" TEXT="dann können sie nur der Reihe nach laufen"/>
|
||||
<node CREATED="1783469992517" ID="ID_1177264229" MODIFIED="1783470001469" TEXT="natürlich erzeugt das so einige Komplikationen"/>
|
||||
<node CREATED="1783470003243" ID="ID_1005057440" MODIFIED="1783470013684" TEXT="und: eine solche Kette kann vorzeitig scheitern"/>
|
||||
</node>
|
||||
<node CREATED="1783470066077" ID="ID_858165857" LINK="https://unixism.net/loti/tutorial/fixed_buffers.html" MODIFIED="1783470085644" TEXT="»fixed buffers« direkt shared gemapped">
|
||||
<node CREATED="1783470086753" ID="ID_522385315" MODIFIED="1783470095701" TEXT="man muß dazu bestimmte Buffer vorher registrieren"/>
|
||||
<node CREATED="1783470096329" ID="ID_1191315406" MODIFIED="1783470104274" TEXT="dann gibt man nur noch den Index des Buffers an"/>
|
||||
<node CREATED="1783470104964" ID="ID_2685011" MODIFIED="1783470118664" TEXT="das geht natürlich nur für bestimmte Lese/Schreiboperationen"/>
|
||||
<node CREATED="1783470119428" ID="ID_931891459" MODIFIED="1783470187977" TEXT="Vorteil: keine Kopie der Daten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
weil der Buffer shared in den Client-Process-Space gemapped ist, muß der Kernel keine Daten mehr explizit in den Ziepuffer im Prozeß kopieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783470603776" ID="ID_492007892" LINK="https://unixism.net/loti/tutorial/register_eventfd.html" MODIFIED="1783470629736" TEXT="kann per poll/epoll signalisieren daß eine io_uring-completion vorliegt"/>
|
||||
</node>
|
||||
<node CREATED="1783471563411" ID="ID_1282916061" MODIFIED="1783471571979" TEXT="Async-Server-Patterns">
|
||||
<node CREATED="1783471572703" ID="ID_1157203614" MODIFIED="1783471574044" TEXT="Reactor">
|
||||
<node CREATED="1783471575007" ID="ID_1734284682" MODIFIED="1783471584374" TEXT="ein Thread der Requests dispatched"/>
|
||||
<node CREATED="1783471588564" ID="ID_452380465" MODIFIED="1783471606480" TEXT="nimmt Requests entgegen und gibt sie an einen passenden Handler weiter"/>
|
||||
<node CREATED="1783471897570" ID="ID_1140725129" MODIFIED="1783471919980" TEXT="Charakteristik: ein Reactor reagiert auf Readiness">
|
||||
<node CREATED="1783471922698" ID="ID_1198048918" MODIFIED="1783471930114" TEXT="typisch für poll / epoll"/>
|
||||
<node CREATED="1783471930679" ID="ID_79266399" MODIFIED="1783471942404" TEXT="das Event ist, wenn der Socket ready ist"/>
|
||||
<node CREATED="1783471943836" ID="ID_1316391544" MODIFIED="1783471950639" TEXT="danach macht der Handler das IO"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783471952182" ID="ID_46196379" MODIFIED="1783471954085" TEXT="Proactor">
|
||||
<node CREATED="1783471954799" ID="ID_526206128" MODIFIED="1783471962028" TEXT="wie der Reactor: ein Handler-Thread"/>
|
||||
<node CREATED="1783471962649" ID="ID_415612091" MODIFIED="1783471971307" TEXT="aber hier sind die Events bereits Completions"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783472019223" ID="ID_1612025217" MODIFIED="1783472086097" TEXT="Achtung: Backpressure notwendig">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1783472033373" ID="ID_662077901" MODIFIED="1783472046527" TEXT="man darf nur so viele Events auf den Weg schicken..."/>
|
||||
<node CREATED="1783472047042" ID="ID_47181594" MODIFIED="1783472070378" TEXT="...wie man derzeit Completions gleichzeitig handhaben kann"/>
|
||||
<node CREATED="1783472070951" ID="ID_277160689" MODIFIED="1783472080389" TEXT="sonst explodiert Speicher/Resourcen-Nutzung"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1519001955679" ID="ID_65625223" MODIFIED="1779386731937" TEXT="Demo-Inhalte">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1779504843301" ID="ID_1215238444" MODIFIED="1779504961470" TEXT="Idee">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1779504852591" ID="ID_628756969" MODIFIED="1779504956035" TEXT="ein Raw-Video-File framewise einlesen">
|
||||
<linktarget COLOR="#d60714" DESTINATION="ID_628756969" ENDARROW="Default" ENDINCLINATION="497;-40;" ID="Arrow_ID_347382746" SOURCE="ID_649621958" STARTARROW="None" STARTINCLINATION="347;-14;"/>
|
||||
<node CREATED="1779504852591" ID="ID_628756969" MODIFIED="1783643338271" TEXT="ein Raw-Video-File framewise einlesen">
|
||||
<linktarget COLOR="#d60714" DESTINATION="ID_628756969" ENDARROW="Default" ENDINCLINATION="626;-59;" ID="Arrow_ID_347382746" SOURCE="ID_649621958" STARTARROW="None" STARTINCLINATION="347;-14;"/>
|
||||
<node CREATED="1783641376247" HGAP="32" ID="ID_1978377711" MODIFIED="1783641391758" TEXT="ist einfach" VSHIFT="3"/>
|
||||
</node>
|
||||
<node CREATED="1779504863066" ID="ID_986008832" MODIFIED="1779504921775" TEXT="jeden Frame in den Output-Code aus dem Video-output-Vortrag schicken"/>
|
||||
<node CREATED="1783642371760" ID="ID_622863035" MODIFIED="1783642377238" TEXT="Konstruktions-Schema">
|
||||
<node CREATED="1783642378650" ID="ID_460419" MODIFIED="1783642391427" TEXT="naheliegend: einen Proactor zeigen">
|
||||
<node CREATED="1783642938966" ID="ID_1117409154" MODIFIED="1783642955536" TEXT="mäßig sinnvoll"/>
|
||||
<node CREATED="1783642956739" ID="ID_141690825" MODIFIED="1783642968326" TEXT="hier nur ein Consumer"/>
|
||||
</node>
|
||||
<node CREATED="1783642985618" ID="ID_169416260" MODIFIED="1783642994611" TEXT="oder einen pull-Worker">
|
||||
<node CREATED="1783642995707" ID="ID_216666777" MODIFIED="1783642999794" TEXT="das wäre näher an Lumiera"/>
|
||||
<node CREATED="1783643000727" ID="ID_737342556" MODIFIED="1783643655114" TEXT="der würde jeweils nur die Queue ausräumen"/>
|
||||
<node CREATED="1783643039177" ID="ID_1046849410" MODIFIED="1783643729328" TEXT="und eine Flag am Buffer setzen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...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.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783643047694" ID="ID_887714759" MODIFIED="1783643329861" TEXT="verwende einen Buffer-Ring">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1783643760643" ID="ID_697288367" MODIFIED="1783644233208" TEXT="braucht Flow-Steuerung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783644313430" ID="ID_170028474" MODIFIED="1783644320854" TEXT="Prototyp entwickeln">
|
||||
<node CREATED="1783644336145" ID="ID_413309976" MODIFIED="1783644338390" TEXT="Skelett">
|
||||
<node CREATED="1783644339455" ID="ID_932453573" MODIFIED="1783644342669" TEXT="CMake"/>
|
||||
<node CREATED="1783644343706" ID="ID_481307677" MODIFIED="1783644354828" TEXT="ein GTK-Rahmen (wie letztes Jahr)"/>
|
||||
<node CREATED="1783644357376" ID="ID_1687423764" MODIFIED="1783644363091" TEXT="ein Worker-Thread"/>
|
||||
<node CREATED="1783644382004" ID="ID_222096554" MODIFIED="1783644392847" TEXT="Handler">
|
||||
<node CREATED="1783644394013" ID="ID_599467746" MODIFIED="1783644398783" TEXT="Completion-Handler"/>
|
||||
<node CREATED="1783644399671" ID="ID_1684157516" MODIFIED="1783644406037" TEXT="Submission-Handler"/>
|
||||
<node CREATED="1783644407569" ID="ID_69520880" MODIFIED="1783644412668" TEXT="Display-Handler"/>
|
||||
</node>
|
||||
<node CREATED="1783644425567" ID="ID_238189215" MODIFIED="1783644429274" TEXT="Flow-Steuerung">
|
||||
<node CREATED="1783644430659" ID="ID_269686877" MODIFIED="1783644452555" TEXT="Aufrabe: Vorlauf steuern">
|
||||
<node CREATED="1783644529049" ID="ID_486151338" MODIFIED="1783644875737" TEXT="zwei Phasen (Chase/Lock)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1783644878986" ID="ID_629406693" MODIFIED="1783644997672" TEXT="Problem: Anfangs-Spitze">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1781400461948" FOLDED="true" ID="ID_1876863038" MODIFIED="1783362593603" TEXT="Laptop">
|
||||
|
|
@ -1779,9 +2199,13 @@
|
|||
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
|
||||
<icon BUILTIN="wizard"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1779504789243" ID="ID_649621958" MODIFIED="1779504956035" TEXT="Klären: kann man mit IO_URING gezielt bestimmte Bereiche eines Files lesen?">
|
||||
<arrowlink COLOR="#d60714" DESTINATION="ID_628756969" ENDARROW="Default" ENDINCLINATION="497;-40;" ID="Arrow_ID_347382746" STARTARROW="None" STARTINCLINATION="347;-14;"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1779504789243" ID="ID_649621958" MODIFIED="1783643338271" TEXT="Klären: kann man mit IO_URING gezielt bestimmte Bereiche eines Files lesen?">
|
||||
<arrowlink COLOR="#d60714" DESTINATION="ID_628756969" ENDARROW="Default" ENDINCLINATION="626;-59;" ID="Arrow_ID_347382746" STARTARROW="None" STARTINCLINATION="347;-14;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1783446197275" ID="ID_1248460230" MODIFIED="1783446216012" TEXT="IO_URING stellt andere IO-Operationen in asynchroner Weise bereit"/>
|
||||
<node CREATED="1783446217077" ID="ID_668632489" MODIFIED="1783446293619" TEXT="insofern ja: readv() / writev() können beliebige Teilbereiche eines Files lesen/schreiben">
|
||||
<arrowlink COLOR="#fdfdca" DESTINATION="ID_1820629134" ENDARROW="Default" ENDINCLINATION="1190;0;" ID="Arrow_ID_836559053" STARTARROW="None" STARTINCLINATION="619;22;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue