Domanda Prestazioni I / O - asincrone vs TPL vs Dataflow vs RX


Ho un pezzo di codice C # 5.0 che genera una tonnellata di I / O di rete e disco. Ho bisogno di eseguire più copie di questo codice in parallelo. Quale tra le seguenti tecnologie è in grado di darmi le migliori prestazioni:

  • metodi asincroni con attendi

  • utilizzare direttamente Task da TPL

  • il nuget TPL Dataflow

  • Estensioni reattive

Non sono molto bravo in questa roba parallela, ma se usassi una leva più bassa, come quella di Thread, potrei darmi delle prestazioni molto migliori che considererei anche quella.


16
2018-04-17 01:05


origine


risposte:


Qualsiasi differenza di prestazioni tra queste opzioni sarebbe irrilevante di fronte a "una tonnellata di I / O di rete e disco".

Una domanda migliore da porsi è "quale opzione è più facile da apprendere e sviluppare con?" O "quale opzione sarebbe meglio mantenere questo codice tra cinque anni?" E per quello suggerirei async prima, o Dataflow o Rx se la tua logica è meglio rappresentata come uno stream.


19
2018-04-17 01:35



È come cercare di ottimizzare la lunghezza del volo transatlantico chiedendo il metodo più rapido per rimuovere la cintura di sicurezza.

Ok, un vero consiglio, dato che ero una specie di idiota

Diamo una risposta utile. Pensa alle prestazioni come a "Classi" di attività - ognuna è un ordine di grandezza più lento (almeno!):

  1. Accesso solo alla CPU, utilizzo della memoria molto ridotto (ad esempio, il rendering di una grafica molto semplice a una GPU molto veloce o il calcolo delle cifre di Pi)
  2. Accesso solo a CPU e cose in memoria, niente su disco (ad esempio, un gioco ben scritto)
  3. Accesso al disco
  4. Accesso alla rete

Se fate anche uno dell'attività n. 3, non ha senso fare ottimizzazioni tipiche delle attività n. 1 e n. 2 come l'ottimizzazione delle librerie di threading: sono completamente oscurate dal successo del disco. Lo stesso vale per i trucchi della CPU: se incorrete costantemente nei caching della memoria L2 / L3, risparmiare alcuni cicli della CPU mediante assemblaggio manuale non vale la pena (ecco perché cose come ciclo di svolgimento di solito sono una cattiva idea in questi giorni).

Quindi, cosa possiamo ricavare da questo? Esistono due modi per rendere più veloce il tuo programma, spostandoti dal # 3 al # 2 (che non è spesso possibile, a seconda di quello che stai facendo), o facendo meno I / O. I / O e velocità di rete è il fattore limitante la velocità nella maggior parte delle applicazioni moderne e quello è cosa dovresti cercare di ottimizzare.


57
2018-04-17 04:25



È una domanda più vecchia, ma per chiunque stia leggendo questo ...

Dipende. Se si tenta di saturare il collegamento 1Gbps con i messaggi 50B, si sarà vincolati alla CPU anche con semplici invii non bloccanti su socket non elaborati. Se, d'altra parte, sei soddisfatto della velocità di trasmissione di 1 Mbps o se i tuoi messaggi sono maggiori di 10 KB, ognuno di questi framework farà il suo lavoro.

Per situazioni con larghezza di banda ridotta, raccomanderei di dare la priorità in base alla facilità d'uso, ovvero async / await, Dataflow, Rx, TPL in questo ordine. Si noti che l'applicazione a larghezza di banda elevata deve essere prototipata come se fosse a larghezza di banda ridotta e ottimizzata in seguito.

Per la vera applicazione a banda larga, posso raccomandare Dataflow su Rx, perché Rx non è progettato per una concorrenza elevata. Raw TPL è il livello inferiore, che garantisce il sovraccarico più basso se è possibile gestire la complessità. Se puoi fare un uso efficiente dei thread dedicati, allora sarebbe ancora più veloce. Async / await vs. Dataflow IMO non fa alcuna differenza di prestazioni. L'overhead sembra paragonabile, quindi scegline uno che si adatti meglio.


12
2017-12-19 16:41