asynchronous - Différence entre POSIX AIO et libaio sous Linux?




linux-kernel (2)

Ce que j'ai l' air de comprendre

POSIX AIO API <aio.h> POSIX AIO 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 sont liés à libaio (-laio).

Ce que je ne peux pas comprendre:

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

O_DIRECT drapeau O_DIRECT obligatoire pour utiliser l'un ou l'autre?

Comme mentionné dans ce post , libaio fonctionne bien sans O_DIRECT lors de l'utilisation de libaio .Okay, compris mais:

Selon Linux System Programming book de R.Love , Linux prend en charge aio (que je suppose est POSIX AIO) sur les fichiers réguliers seulement 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 l'indicateur O_DIRECT fonctionne sans problèmes.


Answers

Sur Linux, les deux implémentations d'AIO sont fondamentalement différentes.

POSIO AIO est une implémentation au niveau de l'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 de faire ceci est la suivante:

  1. cela 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. cela fonctionne sur les fichiers avec la mise en mémoire tampon activée (c.-à-d. pas d'ensemble d'indicateurs O_DIRECT)

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

Le noyau AIO (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. dans un ordre quelque peu optimal on pourrait espérer) sur le disque réel en tant qu'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 bien ou pas du tout avec des E / S asynchrones (et peuvent revenir à la sémantique bloquante), les fichiers doivent être ouverts avec O_DIRECT qui est livré avec beaucoup d'autres restrictions. Demandes d'E / S. Si vous ne parvenez pas à ouvrir vos fichiers avec O_DIRECT, cela peut encore "fonctionner", comme dans le cas où vous récupérez les bonnes données, mais cela n'est probablement pas fait de manière asynchrone, mais retombe à la sémantique de blocage.

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


Les E / S réseau ne constituent pas une priorité pour AIO car tout utilisateur écrivant des serveurs réseau POSIX utilise une approche non bloquante basée sur les événements. L'approche "milliards de threads bloquants" de Java à l'ancienne suce horriblement.

Les E / S d'écriture sur disque sont déjà mises en mémoire tampon et les E / S de lecture de disque peuvent être préchargées dans un tampon en utilisant des fonctions telles que posix_fadvise. Cela laisse des E / S disque non tamponnées directes comme seul but utile pour AIO.

Les E / S directes non tamponnées ne sont vraiment utiles que pour les bases de données transactionnelles, et celles-ci ont tendance à écrire leurs propres threads ou processus pour gérer leurs E / S disque.

Donc, à la fin cela laisse Posix AIO dans la position de ne servir à rien . Ne l'utilisez pas.





linux asynchronous io linux-kernel aio