Un gruppo di ricercatori di università tedesche i risultati , durante il quale sono stati sviluppati 10 varianti di un driver standard per schede di rete Intel Ixgbe (X5xx) in diversi linguaggi di programmazione. Il driver funziona nello spazio utente ed è realizzato in linguaggi come C, Rust, Go, C#, Java, OCaml, Haskell, Swift, JavaScript e Python. Nella scrittura del codice, l'attenzione principale è stata rivolta al raggiungimento delle massime prestazioni possibili, tenendo conto delle caratteristiche di ciascun linguaggio. In termini di funzionalità, tutte le varianti sono identiche e consistono in circa 1000 righe di codice. I risultati del progetto con licenza BSD.
La variante del driver in linguaggio Rust si è rivelata molto vicina in termini di prestazioni al driver di riferimento in linguaggio C. Sotto carico con l'invio simultaneo di blocchi di 32 pacchetti, il driver Rust ha leggermente deluso, ma nei test con oltre 32 pacchetti nel blocco per velocità, non si è praticamente distinto dal driver in C e ha dimostrato prestazioni a livello di elaborazione di 28 milioni di pacchetti al secondo su un server con CPU Xeon E3-1230 v2 3.3 GHz.
La prossima area di prestazioni è stata occupata dai driver in Go e C#, che hanno mostrato risultati abbastanza simili (il driver in Go vinceva nei test con blocchi contenenti fino a 16 pacchetti, ma ha iniziato a perdere nei test con più di 16 pacchetti nel blocco). Con 256 pacchetti nel blocco, la prestazione massima del driver in C# ha raggiunto circa 28 milioni di pacchetti al secondo, mentre il driver in Go ha raggiunto circa 25 milioni di pacchetti al secondo.
Sono seguiti con risultati abbastanza simili i driver in
Java, OCaml e Haskell, che sono già risultati notevolmente indietro rispetto alle opzioni precedentemente esaminate e non sono riusciti a superare la soglia di 12 milioni di pacchetti al secondo. Un ulteriore ritardo è stato mostrato dai driver in Swift e JavaScript, che sono riusciti a elaborare flussi a livello di 5 milioni di pacchetti al secondo.
Ha chiuso il ranking dei driver in Python, che è riuscito a gestire solo 0,14 milioni di pacchetti al secondo. L'implementazione in Python è stata utilizzata per valutare la velocità degli interpreti senza JIT e senza ottimizzazioni specifiche (il codice è stato eseguito utilizzando CPython 3.7 e non era compatibile con PyPy, ma si fa notare che l'ottimizzazione delle strutture di archiviazione dei dati potrebbe aumentare le prestazioni di circa 10 volte).
In aggiunta, sono stati condotti test sui tempi di latenza, che mostrano l'efficacia del buffering e l'impatto del garbage collector. Durante il test, è stata misurata la latenza dopo la reindirizzamento di ogni pacchetto da parte del driver rispetto al tempo di invio noto con precisione. A guidare la classifica sono rimasti i driver in C e Rust, i cui risultati erano praticamente indistinguibili per un flusso di 1 milione di pacchetti al secondo (circa 20 µs). Il driver in Go ha mostrato prestazioni solide, rimanendo solo leggermente indietro rispetto ai leader, mantenendosi anch'esso a livello di 20 µs. Il driver in C# ha mostrato latenze di circa 50 µs.
I driver in JavaScript e Java hanno mostrato le latenze più alte (latenze superiori a 300 µs).
Lo studio è stato condotto per valutare la possibilità di sviluppare driver e componenti di sistema operativo in linguaggi di alto livello rispetto al C. Attualmente, 39 delle 40 problematiche legate alla gestione della memoria in Linux derivano dai driver, pertanto le questioni sull'uso di un linguaggio più sicuro e sul trasferimento dei driver dal kernel allo spazio utente e i produttori stanno già sperimentando attivamente in questa direzione (ad esempio, Google ha sviluppato uno stack TCP per il sistema operativo in linguaggio Go, l'azienda CloudFlare un'implementazione del protocollo QUIC in linguaggio Rust, mentre Apple ha trasferito lo stack TCP sui dispositivi mobili nello spazio utente).
Dallo studio condotto, si conclude che il linguaggio Rust è il miglior candidato per lo sviluppo di driver. Le funzionalità offerte da Rust consentono di risolvere i problemi legati al lavoro a basso livello con la memoria, con una riduzione delle prestazioni di circa il 2%-10% rispetto ai driver scritti in linguaggio C. Anche i linguaggi Go e C# sono considerati idonei per la creazione di componenti di sistema, in situazioni dove sono accettabili latenze a livello di frazioni di millisecondo causate dall'uso del garbage collector.
Fonte: opennet.ru
