web-dev-qa-db-fra.com

Différence entre POSIX AIO et libaio sous Linux?

Ce que je semble comprendre:

POSIX AIO Les API sont prototypées dans <aio.h> et vous liez votre programme avec librt (-lrt), tandis que les API libaio dans <libaio.h> et votre programme est lié à libaio (-laio).

Ce que je ne peux pas comprendre:

1.Le noyau gère-t-il l'une ou l'autre de ces méthodes différemment?

2.Est le O_DIRECT drapeau obligatoire pour utiliser l'un ou l'autre?

Comme mentionné dans cet article , libaio fonctionne très bien sans O_DIRECT lors de l'utilisation de libaio. D'accord, compris mais:

Selon le livre de R.Love Linux System Programming , Linux prend en charge aio ( que je suppose est POSIX AIO) sur les fichiers normaux uniquement si ouvert avec O_DIRECT. Mais un petit programme que j'ai écrit (en utilisant aio.h, lié avec -lrt) qui appelle aio_write sur un fichier ouvert sans le O_DIRECT le drapeau fonctionne sans problème.

50
itisravi

Sous Linux, les deux implémentations AIO sont fondamentalement différentes.

Le POSIX AIO est une implémentation de niveau utilisateur qui effectue des E/S de blocage normales dans plusieurs threads, donnant ainsi l'illusion que les E/S sont asynchrones. La principale raison pour cela est que:

  1. il fonctionne avec n'importe quel système de fichiers
  2. il fonctionne (essentiellement) sur n'importe quel système d'exploitation (gardez à l'esprit que la libc de gnu est portable)
  3. il fonctionne sur les fichiers avec la mise en mémoire tampon activée (c'est-à-dire aucun indicateur O_DIRECT défini)

Le principal inconvénient est que la profondeur de votre file d'attente (c'est-à-dire le nombre d'opérations en suspens que vous pouvez avoir en pratique) est limitée par le nombre de threads que vous choisissez d'avoir, ce qui signifie également qu'une opération lente sur un disque peut bloquer une opération allant vers un disque différent. Cela affecte également les E/S (ou le nombre) vues par le noyau et le planificateur de disque.

L'AIO du noyau (c'est-à-dire io_submit () et.al.) est le support du noyau pour les opérations d'E/S asynchrones, où les requêtes io sont réellement mises en file d'attente dans le noyau, triées par le planificateur de disque que vous avez, probablement certaines d'entre elles sont transmises ( dans un ordre quelque peu optimal, on peut espérer) sur le disque réel comme des opérations asynchrones (en utilisant TCQ ou NCQ). La principale restriction de cette approche est que tous les systèmes de fichiers ne fonctionnent pas aussi bien ou pas du tout avec les E/S asynchrones (et peuvent revenir à la sémantique de blocage), les fichiers doivent être ouverts avec O_DIRECT qui vient avec beaucoup d'autres restrictions sur le Demandes d'E/S. Si vous ne parvenez pas à ouvrir vos fichiers avec O_DIRECT, cela peut toujours "fonctionner", car vous obtenez les bonnes données, mais cela ne se fait probablement pas de manière asynchrone, mais revient à bloquer la sémantique.

Gardez également à l'esprit que io_submit () peut réellement bloquer sur le disque dans certaines circonstances.

63
Arvid