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
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.
`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.
mon thread d'io est clairement busy c'est un agent de logs on a du flux constant. je vais tenter avec `SQPOLL`.
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
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.
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`.
ok je note `O_DIRECT` et des writes plus grosses. le `posix_memalign` je l'ai deja pour les buffers d'ingestion.
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.
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.
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.
fixed buffers c'est une bonne idee. ca ressemble a `splice` ou `vmsplice` pour eviter les copies userspace-kernel-userspace. je vais regarder ca.
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.
oui la taille de la ring est 4096. je pense que c'est ok. pas vu de completion queue full.
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.
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.
exactement. y'a de quoi faire. commence par `SQPOLL` c'est le plus simple a implementer et ca donne un bon boost.
d'acc je vais coder ca. merci a vous deux pour les infos precieuses. j'espere voir le CPU enfin se calmer.
Vous devez être connecté pour poster un message !
Recevoir les derniers articles gratuitement en créant un compte !
S'inscrire
rraynaud
Membre depuis le 24/01/2025actif
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.
des idees pour gratter de la perf ?