Utilizzo di chiamate asincrone per operazioni di I / O pesanti: come evitare di schiacciare la CPU?

2

Ho un'applicazione che legge un file binario di grandi dimensioni (1 GB in media) e si comprime in un archivio bzip2. All'inizio ho iniziato a comprimere questi file in modo sincrono, poiché non volevo impedire le prestazioni su un computer client. A volte tuttavia, questi file arrivano a raffica e mi piacerebbe gestire questi file il più rapidamente possibile. Quindi ho riscritto il metodo per utilizzare una chiamata asincrona future . Sono memorizzati in un vettore fino al completamento e quindi vengono distrutti.

Durante il mio stress test, ho notato che avrei inevitabilmente avuto un problema con l'utilizzo della CPU se, diciamo, 5 file entrassero in una volta su una macchina a 4 core. La macchina client sarebbe praticamente inutilizzabile fino al completamento di tutte le operazioni.

Quindi, questo mi porta alla domanda di design. Sono inesperto con i futures e cerco di determinare le migliori pratiche per mitigare l'utilizzo elevato della CPU. Questo è il design che ho in mente ma prima di passare attraverso il problema di battere il punto e virgola, c'è una caratteristica più nativa del futuro di cui non sono a conoscenza?

  • Determina quante CPU sono disponibili per la macchina host
  • Dividere il numero di CPU della metà per evitare più del 50% di utilizzo della CPU dall'applicazione
  • Utilizza un ciclo su un thread separato per gestire gli oggetti futuri memorizzati in vector .
  • Il loop rileva quando un oggetto non è più in ambito e avvia il prossimo vector future oggetto di compressione

Questo sarebbe il modo migliore per andare?

Grazie!

    
posta user0000001 16.06.2016 - 02:59
fonte

2 risposte

14

Sebbene tu possa avere 4 CPU, hai solo un disco fisso (a meno che tu non lo faccia). Le prestazioni totali saranno pertanto limitate dalla velocità di lettura / scrittura dell'unità disco. Più thread non cambieranno quello.

Avere un singolo thread separato per gestire tutto il file IO consentirà alla tua applicazione di rimanere reattiva mentre continua a fare le cose in modo asincrono. Avere più thread che cercano di parlare alla stessa unità è solo perdere tempo, facendoli contendere tutti per una singola risorsa. Le probabilità sono buone che in quest'ultimo caso, peggiorerai le cose a causa della contesa.

Se si desidera veramente che l'utilizzo della propria applicazione abbia un impatto minimo sulle funzionalità della macchina, è necessario concentrarsi sull'utilizzo del disco rigido. Vuoi leggere 1 GB in memoria. Ma questo danneggerà qualsiasi applicazione che tenta di leggere o scrivere sul disco. Pertanto, è possibile utilizzare API di lettura asincrone di livello basso e specifiche della piattaforma per leggere il file in blocchi più piccoli. Leggi forse 5 MB, quindi lascia dormire il thread per alcuni millisecondi per consentire agli altri di provarlo. Quindi leggi altri.

In effetti, se il tuo compressore bzip è in grado di gestirlo, puoi iniziare a fornire i dati che hai parzialmente letto senza dover leggere tutto. Ciò ti impedirà anche di dover allocare e archiviare 1 GB di RAM tutto in una volta.

    
risposta data 16.06.2016 - 03:08
fonte
0

Se la tua macchina diventa inutilizzabile perché hai abbastanza lavoro per 5 thread ma solo 4 core disponibili, è un problema con il tuo sistema operativo o questi 5 thread hanno una priorità troppo alta. Dovresti notare un leggero rallentamento, tutto qui. E i fan che corrono alla massima velocità ovviamente: -)

Un'altra possibilità è che stai esaurendo la RAM. Ancora una volta, un algoritmo di compressione non dovrebbe usare molta RAM. Se stai leggendo l'intero gigabyte nella RAM, 5 volte e il tuo computer ha solo 4 Gigabytes, questo sarà un problema. In tal caso, modifica l'algoritmo per utilizzare meno RAM. La mappatura dei file potrebbe aiutare.

Potrebbe essere che il tuo algoritmo di compressione usi la sincronizzazione nel caso in cui venga chiamato più volte (non rientrante). Nel peggiore dei casi questa sincronizzazione potrebbe richiedere più tempo della compressione stessa. Non farlo.

Se non riesci a trovare una soluzione diversa, utilizza un semaforo che consente di eseguire solo quattro o tre o due o anche solo uno di questi thread.

    
risposta data 18.11.2016 - 12:52
fonte

Leggi altre domande sui tag