Stavo scrivendo un framework di registrazione asincrono, in cui ho avuto più thread che scaricano dati. Ho iniziato a giocare su Boost asio perché offriva alcuni modi semplici per applicare la serializzazione e l'ordinamento. Dato che sono un principiante, ho iniziato il mio design con un thread safe (usato e boost:condition_variable
) bounded_buffer circolare (che in realtà era vettoriale).Boost ASIO IO_SERVICE Implementazione?
Ho scritto un piccolo benchmark semplice per misurare le prestazioni. Il benchmark è solo un singolo thread che registra un milione di messaggi (spingendolo nel buffer) e il mio thread di lavoro si limita ad afferrare i messaggi dalla coda per accedere al file/console/elenco dei logger. (P.S. L'uso di mutex e C.V era corretto, e i puntatori ai messaggi venivano spostati, quindi da quella prospettiva tutto andava bene/efficiente).
Quando ho cambiato attuazione usando invece boost::asio::io_service
e ed avente un singolo filo esecuzione run()
le prestazioni realmente migliorata (in realtà in scala molto bene sull'aumento del numero di messaggi viene registrato in contrasto con le prestazioni degradano nel mio modello semplice iniziale)
Ecco alcune domande che desidero chiarire.
Perché migliorare le prestazioni? (Pensavo che l'implementazione interna di
boost::asio::io_service
abbia una coda di sicurezza dei thread per i gestori, cosa che lo rende molto più efficiente della mia iniziale progettazione di code di sicurezza con thread semplici). Si prega di prendere nota che il mio design è stato ben recensito e non ha avuto difetti in quanto tale (il codice dello scheletro era basato su esempi dimostrati), qualcuno potrebbe fare più luce sui dettagli interni di comeio_service
implementa questo. La seconda osservazione interessante era che su thread in aumento, le mie prestazioni di implementazione iniziale miglioravano ma al costo di perdere la serializzazione/l'ordine, ma le prestazioni si riducevano (leggermente) con boost :: asio (penso che sia perché i miei gestori stavano facendo un compito molto semplicistico e il sovraccarico di commutazione del contesto era degradante, proverò a mettere un compito più complesso e postare le mie osservazioni più tardi).mi piacerebbe davvero sapere se
boost::asio
è solo significato per le operazioni di I/O e di rete o è il mio utilizzo di usarlo per fare compito concomitante (parallelo) attraverso un pool di thread è un buon approccio progettuale. È l'oggettoio_service
destinato a essere utilizzato per gli oggetti di I/O (come scritto nella documentazione), ma ho trovato un modo davvero interessante di aiutarmi a risolvere attività concorrenti (non solo i/o relative alle reti) in modo serializzato (a volte forzando ordinare usando filamenti). Sono nuovo per aumentare, e davvero curioso perché il modello di base non ha funzionato/scala così come quando ho usato boost asio.
Risultati: (in entrambi i appena avuto 1 thread di lavoro)
- 1000 compito: 10 micro secondi/compito in entrambi i casi
- 10000 compito: 80 micro secondi (tampone delimitata), 10 micro secondi in spinta asio
- 100000 compito: 250 micro secondi (tampone bounde), 10 micro secondi in spinta asio
sarebbe interessante k ora come boost risolve il problema di thread thread in io_service
thread safe queue per i gestori (ho sempre pensato che a un certo livello di implementazione debbano usare anche lock e c.v).
Ho usato 'boost :: asio' per gestire altri tipi di attività asincrone (non solo IO di rete) con successo. – Chad
So che questa è una vecchia domanda ma potrebbe essere che (su Windows), ASIO usi le porte di completamento dell'IO e questo potrebbe comportare meno chiamate di sistema in generale. – Pete