À quel moment la lecture asynchrone des E / S disque est-elle plus efficace que synchrone?

22

En supposant qu'il existe un peu de code qui lit les fichiers pour plusieurs consommateurs et que les fichiers sont de n'importe quelle taille arbitraire: à quelle taille devient-il plus efficace de lire le fichier de manière asynchrone? Ou pour le dire autrement, quelle doit être la taille d'un fichier pour qu'il soit plus rapide juste pour le lire de manière synchrone?

J'ai remarqué (et je me trompe peut-être) que lors de la lecture de très petits fichiers, il faut plus de temps pour les lire de manière asynchrone que synchrone (en particulier avec .NET). Je suppose que cela a à voir avec le temps de configuration pour des choses comme les ports d'achèvement d'E / S, les threads, etc.

Y a-t-il une règle d'or pour vous aider ici? Ou dépend-il du système et de l'environnement?

blesh
la source
Pouvez-vous donner le code que vous utilisez pour le benchmark? Je pense que cela ne pourrait se produire que dans le cas où la taille du fichier est inférieure à la taille du tampon interne du lecteur de flux. Mais si vous devez lire autant de petits fichiers, vous rencontrerez probablement d'autres problèmes avec les
E
Je n'ai pas le code à portée de main, je le crains. C'est quelque chose que j'ai rencontré il y a quelque temps et qui me préoccupe depuis. Le code était en .NET et était essentiellement un File.ReadAllBytes () vs FileStream.BeginRead () dans une boucle for
blesh
Lorsque les courbes qui représentent leur efficacité se croisent, et async IO quitte le croisement à une valeur supérieure à la courbe de synchronisation IO.
Thomas Eding,

Réponses:

14

Malheureusement, la réponse est "cela dépend". Il vous serait facile d'écrire un petit programme pour déterminer empiriquement les temps de lecture asynchrone et synchronisée.

Cela dépendra de nombreux facteurs. Sont-ils stockés sur des disques en rotation, un SSD ou un lecteur réseau? Quel type de CPU utilisez-vous? Combien de sockets / cœurs? Utilisez-vous une machine virtuelle ou du bare metal? Utilisez-vous un système d'exploitation ancien ou moderne?

Martin C. Martin
la source
1
Ouais, je pensais autant. Je suppose que j'espérais qu'il y aurait une sorte d'étude à utiliser comme guide ou règle générale.
blesh
9

Async présente 3 avantages principaux:

  1. Il réduit l'utilisation du processeur. Cela peut être utile si vous effectuez également des opérations gourmandes en ressources processeur avec des données que vous venez de lire.
  2. L'utilisation d'une sorte d'infrastructure asynchrone rend le code facile à paralyser. Surtout si vous lisez beaucoup de fichiers.
  3. En envoyant plusieurs demandes de lecture-écriture au système d'exploitation, le système d'exploitation et le matériel informatique peuvent réorganiser ces opérations pour qu'elles soient effectuées plus rapidement. SATA2 a une telle fonctionnalité.

Je crois que le principal avantage de la lecture asynchrone est lorsque vous travaillez avec de nombreux fichiers ou que vous avez besoin de beaucoup de puissance CPU.

Euphorique
la source
Notez pour le point 2 qu'il n'optimisera rien si l'opération d'E / S est le goulot d'étranglement. Les choses sont différentes si vous accédez en parallèle, via RAID ou réseau, à des fichiers situés sur des disques différents.
Arseni Mourzenko
5
Hmm, j'ai du mal à comprendre ce que tu veux dire avec # 1. Je dirais que c'est l'inverse dans la pratique. Parce qu'avec le cas asynchrone, vous changez maintenant votre thread (s) de blocked waiting for I/O(0% CPU) à continue normal processing(> 0% CPU).
Isak Savo
3

Ça dépend

Une chose à garder à l'esprit est le coût d'un changement de contexte entre les processus. Node.JS est conçu tel qu'il est parce qu'il suppose que faire un changement de contexte est très coûteux et que vous aurez sinon beaucoup de processus en attente sur IE qui gâcheront l'ordinateur.

D'un autre côté, Erlang fait un changement de contexte de processus très bon marché afin que tout puisse être synchrone et que le temps d'exécution d'Erlang puisse garder une trace de tout.

Donc, les facteurs à considérer:

  • le coût d'une opération de changement de contexte
  • la vitesse du disque pour les opérations de recherche
  • la vitesse du disque pour les opérations de lecture
  • sont les fichiers en cache

Et je suis sûr que je laisse de côté une demi-douzaine de facteurs

Zachary K
la source
2

Je ne suis pas sûr qu'il y ait un "point" particulier, mais cela a plus de sens lorsque vous avez beaucoup de threads en marche, car cela vous permet de chevaucher vos E / S avec d'autres travaux. Si vous avez des threads de rechange inactifs, la lecture asynchrone ne vous donnera aucun avantage. Ce n'est que lorsque vous avez des files d'attente de travail qui se remplissent et que votre thread peut utilement effectuer d'autres travaux au lieu d'attendre les E / S que l'accès aux fichiers asynchrones donne un avantage.

TMN
la source
oui, c'est tout l'intérêt du multithreading!
Vlad
1

Je pense que le problème ici n'est pas tant la vitesse de lecture que la latence.

Si vous lisez à partir d'un lecteur réseau ou d'un lecteur de disque dur mécanique lent avec de longues files d'attente, les performances prendront un coup de nez pour la lecture. Et si votre application effectue également la lecture dans le fil GUI, auquel cas c'est une très mauvaise application, alors ce sera terrible pour l'utilisateur.

Codeur
la source