Група изследователи от германски университети резултати , в хода на което на различни езици за програмиране са разработени 10 варианта на типичен драйвер за 10-гигабитни мрежови карти Intel Ixgbe (X5xx). Драйверът работи в потребителското пространство и е реализиран на езиците C, Rust, Go, C#, Java, OCaml, Haskell, Swift, JavaScript и Python. При написването на кода основното внимание е отделено на постигането на максимална производителност с оглед на особеностите на всеки език. По функционалност всички варианти са идентични и се състоят от приблизително 1000 реда код. Направленията на проекта под лиценз BSD.
Вариантът на драйвера на езика Rust се оказа много близък по производителност до еталонния драйвер на езика Си. При натоварване с едновременно изпращане на блокове от 32 пакета Rust-драйверът леко изоставаше, но в тестовете с повече от 32 пакета в блока по скорост практически не се отличаваше от драйвера на Си и демонстрираше производителност на ниво обработка от 28 млн пакета в секунда на сървър с CPU Xeon E3-1230 v2 3.3 GHz.
Следващата ниша по производителност заеха драйверите на езиците Go и С#, които показаха достатъчно близки резултати (драйверът на Go печелеше в тестовете с блокове, включващи до 16 пакета, но започна да губи в тестовете с повече от 16 пакета в блока). При 256 пакета в блока пикова производителност на драйвера на C# беше приблизително 28 млн пакета в секунда, а драйвера на Go около 25 млн пакета в секунда.
Нататък с доста близки резултати следваха драйверите на
Java, OCaml и Haskell, които вече значително изоставаха от по-рано разглежданите варианти и не успяха да преодолеят границата от 12 млн пакета в секунда. Още по-голямо изоставане показаха драйверите на Swift и JavaScript, които успяха да обработят потоци на ниво 5 млн пакета в секунда.
Завърши класирането драйверът на езика Python, който успя да обработи само 0.14 млн пакета в секунда. Реализацията на Python беше използвана за оценка на скоростта на работа на интерпретаторите без JIT и без специфични оптимизации (кодът беше изпълняван с използване на CPython 3.7 и не беше съвместим с PyPy, но се подчертава, че оптимизацията на структурите за съхранение на данни би могла да повиши производителността приблизително 10 пъти).
Допълнително бяха проведени тестове за времеви забавяния, които показаха ефективността на буферирането и влиянието на сборника с отпадъци. При тестването се измерваше забавянето след пренасочване на всеки пакет от драйвера в сравнение с точно известното време на изпращане. Лидери остават драйверите на C и Rust, резултатите от които бяха почти неразличими при поток от 1 млн. пакета в секунда (около 20 µs). Драйверът на Go също показа добри резултати, като малко изоставаше от лидерите и също се задържаше на ниво 20 µs. Драйверът на C# показа забавяния от около 50 µs.
Най-големи забавяния показаха драйверите на JavaScript и Java (забавяния над 300 µs).
Изследването бе проведено с цел оценка на възможността за разработка на драйвери и компоненти на операционната система на езици с по-високо ниво от C. В момента 39 от 40 проблема при работа с паметта в Linux са свързани с драйвери, така че въпросите за използването на по-безопасен език и прехвърлянето на драйверите извън ядрото в пространството на потребителя и производителите вече активно експериментират в тази посока (например, Google разработи TCP стек за операционната система на езика Go, компанията CloudFlare реализация на протокола QUIC на езика Rust, компанията Apple премести TCP стековете на мобилните устройства в пространството на потребителя).
В хода на проведената работа е установено, че езикът Rust е най-добрият кандидат за разработка на драйвери. Предоставените възможности в Rust позволяват да се избегнат проблемите, произтичащи от нискоуровната работа с паметта, с намаление на производителността с около 2% - 10% в сравнение с драйверите на C. Езиците Go и C# също са признати за подходящи за създаване на системни компоненти, в ситуации когато приемливо са забавяния на ниво части от милисекунди, причинени от използването на сборника с отпадъци.
Източник: opennet.ru
