Confronto delle prestazioni dei driver di rete nelle versioni in 10 linguaggi di programmazione

Un gruppo di ricercatori delle università tedesche pubblicato risultati l'esperimento, durante il quale sono state sviluppate 10 versioni di un driver standard per schede di rete Intel Ixgbe (X10xx) da 5 gigabit in diversi linguaggi di programmazione. Il driver viene eseguito nello spazio utente ed è implementato in C, Rust, Go, C#, Java, OCaml, Haskell, Swift, JavaScript e Python. Durante la scrittura del codice, l'obiettivo principale era ottenere le migliori prestazioni possibili, tenendo conto delle caratteristiche di ciascun linguaggio. Tutte le opzioni sono identiche nella funzionalità e consistono di circa 1000 righe di codice. Sviluppi del progetto diffusione sotto licenza BSD.

La versione Rust del driver si è rivelata molto vicina in termini di prestazioni al driver di riferimento in linguaggio C. Sotto carico con invio simultaneo di blocchi da 32 pacchetti, il driver Rust era leggermente indietro, ma nei test con più di 32 pacchetti per blocco, la velocità non era praticamente diversa dal driver C e ha dimostrato prestazioni a livello di elaborazione di 28 milioni pacchetti al secondo su un server con CPU Xeon E3-1230 v2 3.3 GHz.

Confronto delle prestazioni dei driver di rete nelle versioni in 10 linguaggi di programmazione

La nicchia successiva in termini di prestazioni è stata occupata dai driver nei linguaggi Go e C#, che hanno mostrato risultati abbastanza vicini (il driver Go ha vinto nei test con blocchi fino a 16 pacchetti e ha iniziato a perdere leggermente nei test con più di 16 pacchetti in un blocco). Con 256 pacchetti per blocco, le prestazioni di picco del driver C# sono state di circa 28 milioni di pacchetti al secondo e del driver Go di circa 25 milioni di pacchetti al secondo.

Successivamente, con risultati abbastanza vicini, sono stati i driver per
Java, OCaml e Haskell, che erano già notevolmente in ritardo rispetto alle opzioni precedentemente considerate e non riuscivano a superare la soglia dei 12 milioni di pacchetti al secondo. I driver Swift e JavaScript hanno mostrato un ritardo ancora maggiore, essendo in grado di elaborare flussi a livello di 5 milioni di pacchetti al secondo.

Il primo posto è stato completato dal driver Python, che è stato in grado di elaborare solo 0.14 milioni di pacchetti al secondo. L'implementazione 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 nota che l'ottimizzazione delle strutture di archiviazione dei dati potrebbe migliorare le prestazioni di circa 10 volte ).

Inoltre, sono stati eseguiti test di latenza per dimostrare l'efficacia del buffering e l'impatto del Garbage Collector. Il test ha misurato la latenza dopo che ciascun pacchetto è stato inoltrato dal driver rispetto al momento esatto in cui è stato inviato. I leader erano ancora i driver C e Rust, i cui risultati erano praticamente indistinguibili per un flusso di 1 milione di pacchetti al secondo (circa 20 µs). Il driver Go si è comportato bene, rimanendo solo leggermente dietro ai leader e rimanendo anch'esso al livello di 20 µs. Il driver C# ha mostrato ritardi di circa 50 µs.
I ritardi più lunghi sono stati mostrati dai driver JavaScript e Java (latenze superiori a 300 µs).

Confronto delle prestazioni dei driver di rete nelle versioni in 10 linguaggi di programmazione

Lo studio è stato condotto per valutare la possibilità di sviluppare driver e componenti del sistema operativo in linguaggi di livello superiore rispetto al C. Attualmente, 39 problemi di memoria su 40 in Linux sono legati ai driver, quindi i problemi legati all'utilizzo di un linguaggio più sicuro e allo spostamento dei driver fuori dal kernel e nello spazio utente rimanere rilevanti e i produttori stanno già sperimentando attivamente in questa direzione (ad esempio, Google ha sviluppato uno stack TCP per il sistema operativo Fucsia in lingua Go, società CloudFlare creato implementazione del protocollo QUIC in Rust, Apple ha spostato lo stack TCP sui dispositivi mobili nello spazio utente).

Nel corso del lavoro si è concluso che il linguaggio Rust è il miglior candidato per lo sviluppo dei driver. Le funzionalità di Rust eliminano i problemi associati alla gestione della memoria di basso livello al prezzo di una perdita di prestazioni compresa tra il 2% e il 10% rispetto ai driver C. Go e C# sono considerati adatti anche per la creazione di componenti di sistema in situazioni in cui è accettabile una latenza inferiore al millisecondo causata dalla garbage collection.

Fonte: opennet.ru

Aggiungi un commento