Optimisation io_uring pour ingestion logs haute perf ca patine

rraynaud 30/01/2026
RÉSOLU
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

salut le monde je bosse sur un agent de logs custom en C qui utilise io_uring pour pousser des blocs de donnees sur disk. l'idee c'est d'avoir zero copie et max de throughput. mais je vois pas les perfs que j'attendais. le cpu est toujours un peu haut pour l'io. je write des buffers de 4k dans des fichiers.

struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_writev(sqe, fd, &iov, 1, offset);
io_uring_sqe_set_data(sqe, some_data);
io_uring_submit(&ring);

des idees pour gratter de la perf ?

30/01/2026 à 22:22

18 commentaires

delorme-tristan
Membre Actif Secouriste
Avatar de delorme-tristan
delorme-tristan
Membre Actif Secouriste

hello t'utilises quelle version du kernel ? io_uring est tres sensible a ca. et t'as pense a IORING_SETUP_SQPOLL ? ca evite les transitions kernel/userspace

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

kernel 5.15. IORING_SETUP_SQPOLL j'y ai pense mais je l'ai pas encore activé. je voulais d'abord voir le comportement sans.

Modifié le 23/05/2026 à 16:20
thibaut66
Membre Secouriste
Avatar de thibaut66
thibaut66
Membre Secouriste

SQPOLL c'est presque obligatoire pour la haute perf si tu veux eviter les syscalls systematiques. ton thread kernel fait le boulot a ta place. mais attention il doit etre suffisamment 'busy' pour justifier le polling constant.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

mon thread d'io est clairement busy c'est un agent de logs on a du flux constant. je vais tenter avec SQPOLL.

Modifié le 23/05/2026 à 16:20
delorme-tristan
Membre Actif Secouriste
Avatar de delorme-tristan
delorme-tristan
Membre Actif Secouriste

tu utilises O_DIRECT ? pour du log c souvent pertinent ca bypass le page cache et evite le double buffering mais ca demande des buffers alignes et de taille multiple du bloc physique du disk

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

non pas O_DIRECT je pensais que le cache systeme serait benefique pour les petites writes. mais si le CPU est haut ca veut ptete dire des copies memoire.

Modifié le 23/05/2026 à 16:20
thibaut66
Membre Secouriste
Avatar de thibaut66
thibaut66
Membre Secouriste

pour les logs O_DIRECT avec des writes de blocs plus grands genre 64k ou 128k c'est souvent mieux. et des buffers alignes comme dit user1. utilise posix_memalign.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

ok je note O_DIRECT et des writes plus grosses. le posix_memalign je l'ai deja pour les buffers d'ingestion.

Modifié le 23/05/2026 à 16:20
delorme-tristan
Membre Actif Secouriste
Avatar de delorme-tristan
delorme-tristan
Membre Actif Secouriste

pense aussi a io_uring_prep_fsync si tu as besoin de garanties de durabilite. et la capacite de batcher tes IOs. plutot que io_uring_submit apres chaque writev, tu peux en cumuler plusieurs et soumettre un coup.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

oui je batch deja un peu je soumets toutes les X writes ou tous les Y ms. le fsync est important mais je le fais pas sur chaque bloc. c'est trop cher.

Modifié le 23/05/2026 à 16:20
thibaut66
Membre Secouriste
Avatar de thibaut66
thibaut66
Membre Secouriste

avec io_uring tu peux aussi utiliser les 'fixed buffers' via io_uring_register_buffers. ca evite au kernel de refaire des mappings memoire a chaque operation. encore un gain.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

fixed buffers c'est une bonne idee. ca ressemble a splice ou vmsplice pour eviter les copies userspace-kernel-userspace. je vais regarder ca.

Modifié le 23/05/2026 à 16:20
delorme-tristan
Membre Actif Secouriste
Avatar de delorme-tristan
delorme-tristan
Membre Actif Secouriste

le nombre de SQEs et CQEs dans ta ring est important aussi. si trop petit tu peux avoir des waits. essaie d'avoir un ring size suffisant pour tes pics de charge.

11/02/2026 à 05:00
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

oui la taille de la ring est 4096. je pense que c'est ok. pas vu de completion queue full.

12/02/2026 à 00:18
thibaut66
Membre Secouriste
Avatar de thibaut66
thibaut66
Membre Secouriste

dernier point: quelle est la profondeur de ta queue disk hardware ? nvme a une profondeur enorme. si ton io_uring n'envoie pas assez d'ops en parallele tu sous-utilises le hardware.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

j'ai du nvme oui. la profondeur c'est pas un souci je crois que ca supporte genre 64k commandes. je dois envoyer plus d'ops en parallele. donc SQPOLL, O_DIRECT, fixed_buffers et des writes plus grosses. ca fait pas mal de pistes.

Modifié le 23/05/2026 à 16:20
delorme-tristan
Membre Actif Secouriste
Avatar de delorme-tristan
delorme-tristan
Membre Actif Secouriste

exactement. y'a de quoi faire. commence par SQPOLL c'est le plus simple a implementer et ca donne un bon boost.

Modifié le 23/05/2026 à 16:20
rraynaud
Auteur Actif
Avatar de rraynaud
rraynaud
Auteur Actif

d'acc je vais coder ca. merci a vous deux pour les infos precieuses. j'espere voir le CPU enfin se calmer.

15/02/2026 à 16:33

Laisser une réponse

Vous devez être connecté pour poster un message !

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire