Comparación do rendemento do controlador de rede en versións en 10 linguaxes de programación

Un grupo de investigadores de universidades alemás publicado resultados experimento, durante o cal se desenvolveron 10 versións dun controlador estándar para tarxetas de rede Intel Ixgbe (X10xx) de 5 gigabits en diferentes linguaxes de programación. O controlador execútase no espazo do usuario e está implementado en C, Rust, Go, C#, Java, OCaml, Haskell, Swift, JavaScript e Python. Á hora de escribir código, o obxectivo principal foi conseguir o mellor rendemento posible, tendo en conta as características de cada lingua. Todas as opcións son idénticas en funcións e constan de aproximadamente 1000 liñas de código. Desenvolvemento do proxecto espallamento baixo a licenza BSD.

A versión Rust do controlador resultou ser moi semellante en rendemento ao controlador de referencia na linguaxe C. Baixo unha carga con envío simultáneo de bloques de 32 paquetes, o controlador Rust estaba lixeiramente atrasado, pero nas probas con máis de 32 paquetes por bloque, a velocidade non era practicamente diferente á do controlador C e demostrou un rendemento a nivel de procesamento de 28 millóns. paquetes por segundo en un servidor con CPU Xeon E3-1230 v2 3.3 GHz.

Comparación do rendemento do controlador de rede en versións en 10 linguaxes de programación

O seguinte nicho en canto a rendemento ocupárono os controladores nas linguaxes Go e C#, que mostraron resultados bastante próximos (o condutor de Go gañou en probas con bloques de ata 16 paquetes, e comezou a perder lixeiramente en probas con máis de 16 paquetes). nun bloque). Con 256 paquetes por bloque, o rendemento máximo do controlador C# foi de aproximadamente 28 millóns de paquetes por segundo e o controlador Go foi de aproximadamente 25 millóns de paquetes por segundo.

A continuación, con resultados bastante próximos, foron os pilotos
Java, OCaml e Haskell, que xa estaban notablemente atrás das opcións consideradas anteriormente e non podían superar a barra de 12 millóns de paquetes por segundo. Os controladores Swift e JavaScript mostraron un atraso aínda maior, podendo procesar fluxos a un nivel de 5 millóns de paquetes por segundo.

A primeira clasificación foi completada polo controlador Python, que só puido procesar 0.14 millóns de paquetes por segundo. A implementación de Python utilizouse para avaliar a velocidade dos intérpretes sen JIT e sen optimizacións específicas (o código executouse mediante CPython 3.7 e non era compatible con PyPy, pero nótase que a optimización das estruturas de almacenamento de datos podería mellorar o rendemento unhas 10 veces). ).

Ademais, realizáronse probas de latencia para mostrar a eficacia do buffering e o impacto do colector de lixo. A proba mediu a latencia despois de que o condutor reenviase cada paquete en comparación coa hora exacta en que se enviou. Os líderes seguían sendo os controladores C e Rust, cuxos resultados eran practicamente indistinguibles para un fluxo de 1 millón de paquetes por segundo (aproximadamente 20 µs). O piloto de Go tivo un bo rendemento, quedando só lixeiramente por detrás dos líderes e mantendo tamén no nivel dos 20 µs. O controlador C# mostrou atrasos de aproximadamente 50 µs.
Os atrasos máis longos foron os controladores de JavaScript e Java (latencias de máis de 300 µs).

Comparación do rendemento do controlador de rede en versións en 10 linguaxes de programación

O estudo realizouse para avaliar a posibilidade de desenvolver controladores e compoñentes do sistema operativo en linguaxes de nivel superior ao C. Actualmente, 39 de cada 40 problemas de memoria en Linux están relacionados cos controladores, polo que os problemas de usar unha linguaxe máis segura e mover os controladores fóra do núcleo e ao espazo do usuario seguen sendo relevantes e os fabricantes xa están experimentando activamente nesta dirección (por exemplo, Google desenvolveu unha pila TCP para o SO Fúcsia en idioma Go, empresa CloudFlare creado implementación do protocolo QUIC en Rust, Apple trasladou a pila TCP dos dispositivos móbiles ao espazo do usuario).

No transcurso do traballo, chegouse á conclusión de que a linguaxe Rust é o mellor candidato para o desenvolvemento de condutores. As capacidades de Rust eliminan os problemas asociados coa xestión de memoria de baixo nivel ao custo dunha perda de rendemento de aproximadamente un 2% a un 10% en comparación cos controladores C. Go e C# tamén se consideran axeitados para crear compoñentes do sistema en situacións nas que é aceptable unha latencia inferior a milisegundos causada pola recollida de lixo.

Fonte: opennet.ru

Engadir un comentario