Primerjava zmogljivosti omrežnega gonilnika v različicah v 10 programskih jezikih

Skupina raziskovalcev z nemških univerz objavljeno Rezultati poskus, med katerim je bilo razvitih 10 različic standardnega gonilnika za 10-gigabitne omrežne kartice Intel Ixgbe (X5xx) v različnih programskih jezikih. Gonilnik deluje v uporabniškem prostoru in je implementiran v C, Rust, Go, C#, Java, OCaml, Haskell, Swift, JavaScript in Python. Pri pisanju kode je bil glavni poudarek na doseganju najboljše možne zmogljivosti ob upoštevanju značilnosti posameznega jezika. Vse možnosti so po funkcionalnosti enake in obsegajo približno 1000 vrstic kode. Razvoj projekta širjenje pod licenco BSD.

Izkazalo se je, da je različica gonilnika Rust po zmogljivosti zelo blizu referenčnemu gonilniku v jeziku C. Pod obremenitvijo s hkratnim pošiljanjem blokov 32 paketov je gonilnik Rust nekoliko zaostajal, toda pri testih z več kot 32 paketi na blok se hitrost praktično ni razlikovala od gonilnika C in je pokazala zmogljivost na ravni obdelave 28 milijonov paketov na sekundo na strežniku s procesorjem Xeon E3-1230 v2 3.3 GHz.

Primerjava zmogljivosti omrežnega gonilnika v različicah v 10 programskih jezikih

Naslednjo nišo po zmogljivosti so zasedli gonilniki v jezikih Go in C#, ki so pokazali dokaj tesne rezultate (gonilnik Go je zmagal v testih z bloki do 16 paketov in začel rahlo izgubljati v testih z več kot 16 paketi v bloku). Z 256 paketi na blok je bila največja zmogljivost gonilnika C# približno 28 milijonov paketov na sekundo, gonilnik Go pa približno 25 milijonov paketov na sekundo.

Sledila sta z dokaj tesnima izidoma voznika za
Java, OCaml in Haskell, ki so že opazno zaostajali za prej obravnavanimi možnostmi in niso mogli preseči letvice 12 milijonov paketov na sekundo. Gonilnika Swift in JavaScript sta pokazala še večji zaostanek, saj sta lahko obdelala tokove na ravni 5 milijonov paketov na sekundo.

Vrhunsko uvrstitev je dopolnil gonilnik Python, ki je zmogel obdelati le 0.14 milijona paketov na sekundo. Implementacija Python je bila uporabljena za oceno hitrosti tolmačev brez JIT in brez posebnih optimizacij (koda je bila izvedena z uporabo CPython 3.7 in ni bila združljiva s PyPy, vendar je opozorjeno, da bi lahko optimizacija struktur za shranjevanje podatkov izboljšala zmogljivost za približno 10-krat ).

Poleg tega so bili izvedeni testi zakasnitev, da bi pokazali učinkovitost medpomnjenja in vpliv zbiralnika smeti. Testiranje je izmerilo zakasnitev po tem, ko je gonilnik posredoval vsak paket, v primerjavi s točnim časom, ko je bil poslan. Še vedno sta bila vodilna gonilnika C in Rust, katerih rezultati so bili praktično nerazločljivi pri pretoku 1 milijona paketov na sekundo (približno 20 µs). Voznik Go se je dobro odrezal, le malo je zaostal za vodilnima in prav tako ostal na ravni 20 µs. Gonilnik C# je pokazal zakasnitve približno 50 µs.
Najdaljše zakasnitve so pokazali gonilniki JavaScript in Java (latence več kot 300 µs).

Primerjava zmogljivosti omrežnega gonilnika v različicah v 10 programskih jezikih

Študija je bila izvedena za oceno možnosti razvoja gonilnikov in komponent operacijskega sistema v jezikih višje ravni od C. Trenutno je 39 od 40 težav s pomnilnikom v Linuxu povezanih z gonilniki, torej težave z uporabo varnejšega jezika in premikanjem gonilnikov iz jedra v uporabniški prostor. ostanejo relevantni in proizvajalci že aktivno eksperimentirajo v tej smeri (Google je na primer razvil sklad TCP za OS Fuksija v jeziku Go, podjetje CloudFlare ustvarili implementacijo protokola QUIC v Rust je Apple premaknil sklad TCP na mobilnih napravah v uporabniški prostor).

Med delom je bilo ugotovljeno, da je jezik Rust najboljši kandidat za razvoj gonilnikov. Zmogljivosti Rusta odpravljajo težave, povezane z upravljanjem pomnilnika na nizki ravni, za ceno približno 2 % do 10 % izgube zmogljivosti v primerjavi z gonilniki C. Go in C# veljata tudi za primerna za ustvarjanje sistemskih komponent v situacijah, ko je sprejemljiva zakasnitev, ki je manjša od milisekunde zaradi zbiranja smeti.

Vir: opennet.ru

Dodaj komentar