A che punto la lettura asincrona degli I / O del disco è più efficiente di quella sincrona?


22

Supponendo che ci sia un po 'di codice che legge i file per più utenti e che i file sono di qualsiasi dimensione arbitraria: a quale dimensione diventa più efficiente leggere il file in modo asincrono? O per dirla in altro modo, quanto deve essere piccolo un file affinché sia ​​più veloce solo per leggerlo in modo sincrono?

Ho notato (e forse non sono corretto) che durante la lettura di file molto piccoli, ci vuole più tempo per leggerli in modo asincrono che sincrono (in particolare con .NET). Suppongo che ciò abbia a che fare con il tempo di configurazione per cose come porte di completamento I / O, thread, ecc.

C'è qualche regola empirica per dare una mano qui? O dipende dal sistema e dall'ambiente?


Puoi fornire il codice che usi per il benchmark? Penso che ciò possa accadere solo nel caso in cui la dimensione del file sia inferiore alla dimensione del buffer interno del lettore di stream. Ma se devi leggere che molti piccoli file probabilmente
colpirai

Non ho il codice a portata di mano, temo. È qualcosa che mi sono imbattuto un po 'di tempo fa ed è stato nella mia mente da allora. Il codice era in .NET ed era essenzialmente un semplice File.ReadAllBytes () vs FileStream.BeginRead () in un ciclo for
blesh,

Quando le curve che rappresentano la loro efficienza si incrociano e l'IO asincrono esce dall'incrocio a un valore superiore rispetto alla curva dell'IO di sincronizzazione.
Thomas Eding,

Risposte:


14

Sfortunatamente, la risposta è "dipende". Sarebbe facile per te scrivere un piccolo programma per determinare empiricamente i tempi delle letture asincrone e sincronizzate.

Dipenderà da molti fattori. Sono memorizzati su dischi rotanti, SSD o un'unità di rete? Che tipo di CPU stai usando? Quanti socket / core? Sei in esecuzione in una macchina virtuale o bare metal? Stai eseguendo un sistema operativo antico o moderno?


1
Sì, ho pensato tanto. Immagino che sperassi ci fosse una sorta di studio da usare come guida o regola empirica.
carne

9

Async ha 3 principali vantaggi:

  1. Riduce l'utilizzo della CPU. Questo potrebbe essere utile se stai anche eseguendo operazioni pesanti per la CPU con i dati che hai appena letto.
  2. L'uso di una sorta di infrastruttura asincrona rende il codice facile da paralizzare. Soprattutto se stai leggendo molti file.
  3. Inviando più richieste di lettura / scrittura al sistema operativo, il sistema operativo e HW possono riordinare tali operazioni per completarle più rapidamente. SATA2 ha tale funzionalità.

Credo che il vantaggio principale della lettura asincrona sia quando lavori con molti file o hai bisogno di molta potenza della CPU.


Nota per il punto 2 che non ottimizzerà nulla se l'operazione di I / O è il collo di bottiglia. Le cose sono diverse se si accede in parallelo, tramite RAID o rete, a file che si trovano su dischi diversi.
Arseni Mourzenko,

5
Hmm, ho problemi a capire cosa intendi con il n. 1. Direi che è il contrario nella pratica. Perché con il caso asincrono, ora stai cambiando i tuoi thread da blocked waiting for I/O(0% CPU) a continue normal processing(> 0% CPU).
Isak Savo,

3

Dipende

Una cosa da tenere a mente è quanto è costoso un cambio di contesto tra processi. Node.JS è progettato così com'è perché si presume che fare un cambio di contesto sia molto costoso e altrimenti si avranno molti processi in attesa su IE che impantaneranno il computer.

D'altra parte, Erlang rende un cambio di contesto di processo molto economico, quindi tutto può essere sincrono e il tempo di esecuzione di Erlang può tenere traccia di tutto.

Quindi i fattori da considerare:

  • il costo di un'operazione di cambio di contesto
  • la velocità del disco per le operazioni di ricerca
  • la velocità del disco per le operazioni di lettura
  • sono i file nella cache

E sono sicuro che tralascerò una mezza dozzina di fattori


2

Non sono sicuro che ci sia un "punto" particolare, ma ha più senso quando hai molti thread funzionanti, in quanto ti consente di sovrapporre l'I / O con altri lavori. Se hai thread di riserva inattivi, la lettura asincrona non ti darà alcun vantaggio. È solo quando le code di lavoro si riempiono e il tuo thread potrebbe fare utilmente altro lavoro invece di aspettare l'I / O che l'accesso asincrono ai file offre alcun vantaggio.


sì, questo è il punto centrale del multithreading!
Vlad,

1

Penso che il problema qui non sia tanto la velocità di lettura, quanto la latenza.

Se stai leggendo da un'unità di rete o da un disco rigido meccanico lento con lunghe code, le prestazioni richiederanno un buon risultato per la lettura. E se anche la tua app sta eseguendo la lettura nel thread della GUI, nel qual caso è un'applicazione molto negativa, sarà terribile per l'utente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.