io_uring perfs bizarres sur NVMe et saturation CPU

noel75 07/07/2025
RÉSOLU
noel75
Auteur Actif
Avatar de noel75
noel75
Auteur Actif

salut tout le monde! j'essaie d'optimiser les i/o sur une appli de base de données custom en utilisant io_uring sur du NVMe. j'attends des perfs de malade mais je suis déçu. iostat montre que le NVMe est pas saturé mais le CPU userspace monte en flèche qd mon appli tourne. je comprends pas.

struct io_uring_params params;
memset(&params, 0, sizeof(params));
params.flags = IORING_SETUP_SQPOLL;
ret = io_uring_queue_init(256, &ring, &params);
// ... submission et completion via io_uring_submit() et io_uring_wait_cqe()
07/07/2025 à 22:31

15 commentaires

jeanne84
Membre Actif
Avatar de jeanne84
jeanne84
Membre Actif

hello! tu utilises ioring_setup_sqpoll c'est un bon début. mais tu utilises aussi io_uring_wait_cqe()? c'est pas idéal pour la perf max avec sqpoll.

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

oui je soumets mes requêtes et après je loop sur io_uring_wait_cqe() pour récupérer les completions. c'est pas le pattern classique?

Modifié le 23/05/2026 à 16:20
julien-laurence
Membre Actif
Avatar de julien-laurence
julien-laurence
Membre Actif

le pattern classique avec SQPOLL pour les perfs max, c'est de ne pas appeler io_uring_wait_cqe qui re-rentre dans le kernel. le but de SQPOLL c'est de garder un kernel thread dédié qui poll les completions et t'évite les syscalls.

Modifié le 23/05/2026 à 16:20
jeanne84
Membre Actif
Avatar de jeanne84
jeanne84
Membre Actif

exact. si tu appelles io_uring_wait_cqe tu gâches l'avantage de SQPOLL. l'idée est de faire du polling en userspace sur le CQ ring sans transitionner vers le kernel. ton CPU userspace monte p-e à cause de ça.

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

ton thread qui fait le io_uring est-il pinner sur un core CPU dédié? si ton appli et le thread io_uring se battent pour le même core, tu perds l'avantage de la latence.

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

non j'ai pas pinner le thread. c'est une bonne idée ça. je vais regarder taskset.

Modifié le 23/05/2026 à 16:20
julien-laurence
Membre Actif
Avatar de julien-laurence
julien-laurence
Membre Actif

vérifie aussi la version de ton kernel. les perfs d'io_uring ont été énormément améliorées dans les versions récentes, genre 5.15+. t'es sur quoi?

14/07/2025 à 11:33
noel75
Auteur Actif
Avatar de noel75
noel75
Auteur Actif

kernel 5.18. donc ça devrait être bon de ce côté.

15/07/2025 à 08:17
jeanne84
Membre Actif
Avatar de jeanne84
jeanne84
Membre Actif

pour éviter le io_uring_wait_cqe, tu peux utiliser io_uring_peek_cqe et ne faire un io_uring_enter avec IORING_ENTER_GETEVENTS seulement quand tu n'as plus rien dans le CQ ring. C'est le vrai polling.

Modifié le 23/05/2026 à 16:20
julien-laurence
Membre Actif
Avatar de julien-laurence
julien-laurence
Membre Actif

ou mieux, io_uring_submit_and_wait avec IORING_ENTER_GETEVENTS en un seul syscall. ça réduit les transitions kernel/userspace.

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

ah ok je vois le topo pour le polling. je pensais que SQPOLL faisait ça tout seul. en gros faut que je gère le polling de la completion queue en userspace et seulement si elle est vide, faire un syscall pour attendre des événements?

Modifié le 23/05/2026 à 16:20
jeanne84
Membre Actif
Avatar de jeanne84
jeanne84
Membre Actif

oui c'est ça l'idée. ou utiliser la fonction qui combine submit et wait en un seul syscall comme mentionné. C'est crucial pour la latence et le CPU.

18/07/2025 à 17:24
jeanne52
Membre
Avatar de jeanne52
jeanne52
Membre

et n'oublie pas l'alignement des buffers pour les I/O. pour le NVMe, souvent du 4k ou la taille de secteur logique du drive. posix_memalign est ton ami ici pour pas avoir de copies inutiles.

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

purée j'avais pas du tout capté cette subtilité de SQPOLL et du IORING_ENTER_GETEVENTS. je pensais que c'était plus simple. je vais recoder ma loop de completion.

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

je viens de tester. le pinning du thread io_uring sur un core dédié et surtout la modif pour utiliser io_uring_peek_cqe puis io_uring_enter avec IORING_ENTER_GETEVENTS quand besoin... c'est le jour et la nuit! le CPU userspace est tombé et la latence a disparu. c'était bien ça le problème. thx à tous!

Modifié le 23/05/2026 à 16:20

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