Explorant io_uring: com Linux accelera les operacions d’entrada/sortida moderna
Introducció
Una de les principals innovacions al kernel de Linux és io_uring (introduït a la versió 5.1 del kernel). És una nova API relacionada amb les operacions d’I/O, optimitzant-ne enormement el seu rendiment.
En aquest post explicarem què és io_uring, com funciona internament, i quins avantatges tècnics aporta respecte a mecanismes clàssics.
Què és io_uring?
io_uring és una interfície d’I/O basada en ring buffers compartits entre espai d’usuari i de kernel. Això permet als programes realitzar operacions d’entrada/sortida fent menys entrades al kernel i, sovint, reduint també canvis de context (millorant la latència i el consum de CPU).
Per què és útil?
Els mecanismes d’I/O més antics tenen limitacions:
read() i write()
-
Sincrònics: Els processos queden bloquejats.
-
Cada operació implica una syscall (afegint sobrecàrrega).
AIO (Linux Async I/O)
-
Poc consistent i incompleta.
-
No suporta totes les operacions.
-
Implementació complicada i lenta.
epoll
Excel·lent per sockets, però amb fitxers normals no pot notificar esdeveniments I/O.
Requereix syscalls.
Arquitectura
io_uring conté dos ring buffers en memòria compartida:
-
Submission queue
Aquest és el ring buffer on les aplicacions envien les peticions I/O.
-
Completion queue
Quan el kernel acaba l’operació, envia el resultat aquí, llesta per al programa.
syscalls
io_uring només necessita dues syscalls per configurar la interfície:
io_uring_setup() i io_uring_enter() per empènyer entrades quan és necessari.
La resta de comunicacions passa pel buffer de memòria compartida, sense syscalls per cada petició.
SQPOLL
A més, amb el mode SQPOLL, el kernel dedica un thread per processar peticions sense que l’usuari faci syscalls, reduint la sobrecàrrega.
Avantatges principals
-
Syscalls reduides
La major part de la feina es fa en memòria compartida, pel que reduim els canvis de context.
-
Menor latència
Comparat amb altres mètodes, ofereix una latència molt menor.
-
Operacions unificades
Permet diverses operacions, com:
-
Fitxers
-
Sockets
-
Pipes
-
BPF
-
-
Zero-copy
io_uring suporta operacions zero-copy (veure aquí) en sockets i altres operacions específiques, reduint còpies de dades innecessàries.
-
Disseny escalable
Està pensat per escalar multicore, amb una capacitat de paral·lelisme enorme.
Conclusió
io_uring és de les innovacions més importants dels últims anys. Amb la seva arquitectura de memòria compartida i minimitzant les syscalls, dóna un rendiment molt superior a aplicacions que requereixen moltes peticions I/O.
I fins aquí el post d’avui. Si t’ha semblat útil pots deixar un comentari i compartir-lo. Ens veiem al següent!



