LINUX.ORG.RU

Biscuit: монолитное POSIX-совместимое ядро на Go

 , ,


6

4

Ядро было написано аспирантом MIT Cody Cutler в рамках исследования «The benefits and costs of writing a POSIX kernel in a high-level language» и доступно на GitHub странице MIT PDOS (Parallel and Distributed Operating Systems group at MIT CSAIL) под лицензией MIT.

Biscuit неплохо документирован и содержит 27 тысяч строк на Go, из которых всего 90 функций содержат небезопасные вызовы («unsafe»), необходимые для задач вроде доступа к регистрам процессора. Есть также небольшой загрузчик, написанный на ассемблере.

Особенности:

Скомпилировать и опробовать ядро довольно просто:

git clone https://github.com/mit-pdos/biscuit.git
cd biscuit/src
./make.bash && make -C ../biscuit qemu CPUS=2
При этом сборка с нуля занимает всего 38 секунд, из которых 33 секунды приходится на немного модифицированный рантайм Go, и всего 5 секунд непосредственно на сборку ядра.

Интересны результаты исследования. После проведения тестов производительности на таких приложениях, как NGINX, Redis, и CMailbench — обнаружилось, что сравнение производительности эквивалентных путей кода на Си и на Go показало всего 15% разницы. Доля процессорного времени, потребляемого сборкой мусора и проверками безопасности, по результатам авторов статьи — составляет менее 15%.

>>> Подробности

Ответ на: комментарий от anonymous

Для первокурсника всё же титаническая. Для дипломника - уже нет.

tailgunner ★★★★★ ()
Ответ на: комментарий от DAGAZ

Это тебе не комменты на лоре строчить

anonymous ()
Ответ на: комментарий от tailgunner

Также беглого взгляда на реализацию tcp стека в промышленном линуксе и в бисквите достаточно, чтобы понять, что задачи, выполняемые и там и там, принципиально различаются
В линуксовой реализации есть функции на 10 экранов с изощренной логикой, а в бисквитной реализаци функции едва занимают два экрана

kto_tama ★★★★★ ()

Как же пацанам просто нассать в уши.

NGINX, Redis, и CMailbench

Казалось бы, после такого можно было бы сносить это мусор и выкидывать на помойку, т.к. это колхозные манипуляции? Но вот вопрос - кто-то вообще их осознал? Я не вижу.

Что мы видим в агитке?

сравнение производительности эквивалентного кода на Си и на Go показало всего 15% разницы

Мне лень гуглить и читать этот мусор - есть ли там подобная фраза, либо нет. Но в данном случае за такую фразу надо сносить сразу и слёту.

Первое - никакая производительность эквивалентного кода на Си и Go не измерялась, измерялась производительно С/С++-юзерспей кода.

Второе - никаких 15% разницы нет, 15% разница есть только тогда, когда измерения проводились на 100% sys time. Чего, очевидно, нет.

Мало того, что нет 100% - нет вообще ничего. Я полистал этот мусорный pdf - там никакой конкретики нет. Что именно они бенчили и на чём. Во-первых это уже не измерения т.к. их невозможно воспроизвести. Во-вторых sys time там ничтожно мало, а это значит, что разница в 15% при 15% sys time будет не в 15%. 75 + 15 -> 75 + 30, либо ДВА раза, а не 15%.

На кого рассчитан этот треш - неясно. На тех, кто считать не умеет? В любом случае - всё это неважно. Как только кто-то бенчит ядро на мусорном юзерпейс-коде - это либо идиот, либо манипулятор. Другого быть не может. К тому же были самый убогие бенчмарки. Надо было ещё пхп взять.

nebanbmenyapls ()
Ответ на: комментарий от anonymous

Ага, возьми среднего первокурсника среднего вуза в России, он даже пятистрочный скрипт на баше написать обосрётся.

WitcherGeralt ()

SeaBIOS 1.11.0

что-то они SeaBIOS несвежий используют

SakuraKun ★★ ()
Ответ на: комментарий от nebanbmenyapls

кто-то вообще их осознал? Я не вижу

Не видишь, ибо никого особенно эта чушь не заинтересовала.

WitcherGeralt ()

писать ось под х86 - гиблое дело. это я как сожравший стаю собак на сём деле знаю. тут тебе и тонны багов в процах(sysret например), и acpi который придуман сраными оглоедами. и дрова ты с линукса не сдерёшь - там юзерспейс надо часто тащить а он прибит то к иксам, то вообще к glib.

i36_zubov ()
Ответ на: комментарий от linux-org-ru

Ведь это первое из рабочих?

А были на go до этого?

imul ★★★★★ ()
Ответ на: комментарий от DAGAZ

достаточно крепкое

как это измерить?

imul ★★★★★ ()
Ответ на: комментарий от WitcherGeralt

Твои показания не вяжутся с объективными наблюдениями. Если никого не заинтересовало - то почему вся первая страница - это срач на тему 15% и сравнения линукса и этой поделки?

nebanbmenyapls ()
Ответ на: комментарий от kto_tama

Размер кода - 100 килобайт

Надо больше комментариев и имена переменных и функций подлиннее. Можно будет и 100 мегабайт забабахать.

imul ★★★★★ ()
Ответ на: комментарий от imul

А были на go до этого?

Где то мимо уха слышал вроде. А может про это же ядро и слышал. Ну уверен короче.

linux-org-ru ()

сравнение производительности эквивалентного кода

эквивалентного

ой кто-то брешет.

i36_zubov ()
Ответ на: комментарий от i36_zubov

и дрова ты с линукса не сдерёшь - там юзерспейс надо часто тащить

На правах оффтопа: как определить, что мне нужно писать именно модуль, а не баш-скрипт, дёргающий девайс через /dev/i2c? Среди модулей я вижу много всего, что можно было бы реализовать в бзерспейсе, это делает меня быть в состоянии замешательства.

sleeply4cat ()
Ответ на: комментарий от sleeply4cat

как определить, что мне нужно писать именно модуль, а не баш-скрипт, дёргающий девайс через /dev/i2c?

Модуль надо писать тогда, когда нужно создать программно-доступную сущность (шелл-скрипт такой сущности не создает) или когда по-другому нормально не сделаешь (доступ к DMA или прерываниям).

tailgunner ★★★★★ ()
Ответ на: комментарий от anonymous

В зависимости от наличия внутренненго содержания - не вижу существенной разницы между тем чтобы излагать свои мысли человеку / излагать свои мысли машине.

DAGAZ ()

это всё херня. напишите мне браузер с 27 тысяч строк на Go)

darkenshvein ★★★★ ()
Ответ на: комментарий от tailgunner

Что есть «программно-доступная сущность» в данном контексте?

Сервер MySQL вполне себе доступен без модулей (AFAIK), а всякий шлак в /dev/ можно развести через FUSE. Наверняка какой-нибудь упоротый азиат уже запилил возможность сделать это через баш.

sleeply4cat ()
Ответ на: комментарий от anonymous

Переносимость - не «удобство программистов»?

переносимость - это бабло. так как позволило сократить сроки и кол-во программистов в миграциях с одной железки на другую.

vtVitus ★★★★★ ()
Ответ на: комментарий от nebanbmenyapls

Анонимусов я не посчитал, а остальной срач там про удобство программиста против производительности.

WitcherGeralt ()
Ответ на: комментарий от sleeply4cat

всякий шлак в /dev/ можно развести через FUSE

Вот это и будет программно-доступная сущность.

tailgunner ★★★★★ ()
Ответ на: комментарий от WitcherGeralt

Ты опять путаешься в показаниях? Мне тебе перечислить все комменты на эту тему из первой страницы? Или ты сам осознаешь всё нелепость своих попыток?

nebanbmenyapls ()
Ответ на: комментарий от ncrmnt

показало всего 15% разницы (однако garbage collector в тестах производительности почти не вызывался).

Отличный бенчмарк! (сарказм)

Это у хвостострела подгорело от результатов и он эту правку внес, в оригинале новости не было.

По производительности garbage collector результаты в статье тоже есть:

8.5 GC delays

We measured the delays caused by garbage collection (in- cluding interleaved concurrent work) during the execution of NGINX, aggregated by allocator call, system call, and NGINX request. 0.7% of heap allocator calls are delayed by collection work. Of the delayed allocator calls, the average delay is 0.9 microseconds, and the worst case is 115 microseconds, due to marking a large portion of the TCP connection hashtable.

2% of system calls are delayed by collection work; of the delayed system calls, the average delay is 1.5 microseconds, and the worst case is 574 microseconds, incurred by a poll system call that involved 25 allocatorcalls that performed collection work.

22% of NGINX web requests are delayed by collection work. Of the delayed requests, the average total collec- tion delay is 1.8 microseconds (out of an average request processing time of 45 microseconds). Less than 0.3% of requests spend more than 100 microseconds garbage collecting. The worst case is 582 microseconds, which includes the worst-case system call described above.

jollheef ★★★★★ ()

Biscuit

Чорт, я хотел своё ядро назвать IrishStew...

hobbit ★★★★★ ()
Ответ на: комментарий от dekar

Кто готов срезать 15% производительности своего процессора ради удобства программистов, не осиливших нормально спроектровать архитектуру ядра чтобы GC был не нужен?

Есть подозрение, что если оно взлетит, то нас просто не спросят. :(

hobbit ★★★★★ ()
Ответ на: комментарий от hobbit

Интереснее другое - если оно взлетит, то как писать для него драйверы? Загружаемых модулей там нет.

tailgunner ★★★★★ ()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от i36_zubov

и дрова ты с линукса не сдерёшь - там юзерспейс надо часто тащить а он прибит то к иксам, то вообще к glib

А можно про это чуточку подробнее рассказать на конкретных примерах?

hobbit ★★★★★ ()

Не могу судить о качестве проделанной работы, поскольку лень читать, но для аспиранта она имеет двойной профит: 1) Он получает PhD. 2) У него ядро на Go в портфолио.

Я считаю это вин для него.

undefiened ()
Ответ на: комментарий от jollheef

показало всего 15% разницы (однако garbage collector в тестах производительности почти не вызывался).

Отличный бенчмарк! (сарказм)

Это у хвостострела подгорело от результатов и он эту правку внес, в оригинале новости не было.

Это было в статье. Релевантные цитаты:

«The benchmarks allocate no heap memory in steady-state, so Biscuit’s garbage collector is not invoked.»

«These results give a feel for performance differences due just to choice of language. They don’t involve garbage collection»

Так что да, GC почти не вызывался или не вызывался вообще (в разных бенчмарках). Это не у меня подгорело.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

в том ядре, которое позвонило на диск, тоже ооочень много чего не было ;)

yyk ★★★★★ ()
Ответ на: комментарий от tailgunner

если оно взлетит

Не думаю. Это чисто исследовательское ядро под один проект. Обычно после статьи на подобное забивают.

Интереснее другое - если оно взлетит, то как писать для него драйверы? Загружаемых модулей там нет.

Через Go plugin, например.

jollheef ★★★★★ ()
Ответ на: комментарий от tailgunner

Это не у меня подгорело.

А выглядело именно так. Твои правки вводили в заблуждение, так как игнорировали значимую часть статьи о том, какую роль в производительности Nginx играл garbage collector.

На данный момент вывод в новости является таким же, какой и вывод статьи: «The fraction of CPU time consumed by garbage collection and safety checks is less than 15%. The paper compares the performance of equivalent kernel code paths written in C and Go, finding that the C version is about 15% faster.».

Из той же статьи:

8.5 GC delays

We measured the delays caused by garbage collection (in- cluding interleaved concurrent work) during the execution of NGINX, aggregated by allocator call, system call, and NGINX request. 0.7% of heap allocator calls are delayed by collection work. Of the delayed allocator calls, the average delay is 0.9 microseconds, and the worst case is 115 microseconds, due to marking a large portion of the TCP connection hashtable.

2% of system calls are delayed by collection work; of the delayed system calls, the average delay is 1.5 microseconds, and the worst case is 574 microseconds, incurred by a poll system call that involved 25 allocatorcalls that performed collection work.

22% of NGINX web requests are delayed by collection work. Of the delayed requests, the average total collec- tion delay is 1.8 microseconds (out of an average request processing time of 45 microseconds). Less than 0.3% of requests spend more than 100 microseconds garbage collecting. The worst case is 582 microseconds, which includes the worst-case system call described above.

jollheef ★★★★★ ()
Ответ на: комментарий от tailgunner

Давай я заставлю тебя рыдать и удалять мои сообщения. Но не волнуйся, лор всё помнит.

Идём сюда: Rust 1.25.0

Rust это системный язык программирования, нацеленный на надёжность, скорость и параллельное выполнение.

Для того, чтобы не начал юлить в сторону «я не видел и не могу» - Rust 1.25.0

Контекст: Biscuit: монолитное POSIX-совместимое ядро на Go

Так что да, GC почти не вызывался или не вызывался вообще (в разных бенчмарках). Это не у меня подгорело.
Семантика языка завязана на сборку мусора.

А теперь вопрос. Почему в той новости про быстрый раст нету сноски «в составе llvm, т.е. в составе крестового рантайме». Почему когда сравнивалась производительность раста - ты не делал эту сноску? Почему ты не приходил и не редактировал темы?

Почему ты не упоминаешь, что «быстрый» в контексте раст существует только в контексте llvm - это часть дизайна языка. Такая же, как и GC в го.

Таким образом, что го( по твоей логике) не состоятелен с гц, то раст несостоятелен без llvm. Где сноски?

nebanbmenyapls ()
Ответ на: комментарий от jollheef

Показываю как надо. Хочешь шоу - можешь повторить, ведь тебя он не потрёт. А потом он убежит отсюда так быстро как только сможет.

nebanbmenyapls ()
Ответ на: комментарий от jollheef

Еще раз, медленно:

«allocate no heap memory in steady-state, so Biscuit’s garbage collector is not invoked»

«They don’t involve garbage collection; for that, see §8.4 and §8.6»

tailgunner ★★★★★ ()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от jollheef

пфффф. а как там х86-64 сделать? там же 386 захардкодено.

i36_zubov ()
Ответ на: комментарий от tailgunner

Еще раз, вывод статьи: «The fraction of CPU time consumed by garbage collection and safety checks is less than 15%. The paper compares the performance of equivalent kernel code paths written in C and Go, finding that the C version is about 15% faster.».

Исследования производительности были в том числе для работы GC, цитаты я приводил выше, причем уже дважды.

jollheef ★★★★★ ()
Последнее исправление: jollheef (всего исправлений: 1)
Ответ на: комментарий от i36_zubov

пфффф. а как там х86-64 сделать? там же 386 захардкодено.

386 захардкодено

Где?

jollheef ★★★★★ ()
Ответ на: комментарий от CYB3R

Оно же гвоздями к x86 прибито.

btw, у Go — самый удобный кросс-компилятор из всех, с какими я сталкивался. После работы в embedded с крипотой из Сишных тулчейнов — только в радость.

Правда с особенностью — оно работает очень классно только до тех пор, пока не используется Cgo.

А так: GOARCH=arm64 GOOS=linux go build, и ты получаешь на выводе бинарник под arm64 для Linux без мозгонасилия.

jollheef ★★★★★ ()
Последнее исправление: jollheef (всего исправлений: 2)
Ответ на: комментарий от jollheef

А так: GOARCH=arm64 GOOS=linux go build, и ты получаешь на выводе бинарник под arm64 для Linux без мозгонасилия.

так в кросскомпиляторе gcc это вообще не надо указывать

anonymous ()
Ответ на: комментарий от anonymous

так в кросскомпиляторе gcc это вообще не надо указывать

Да, но только если это кросскомпилятор.

Я не указал, что исходный компилятор Go и является кросс-компилятором для всех архитектур, поддерживаемых Go. Собственно, в этом и удобство.

Тебе достаточно исходного компилятора Go, а дальше любой вариант из доступных OS/Arch:

android:386 amd64 arm arm64
darwin: 386 amd64 arm arm64
dragonfly: amd64
freebsd: 386 amd64 arm
js: wasm
linux: 386 amd64 arm arm64 mips mips64 mips64le mipsle ppc64 ppc64le riscv64 s390x
nacl: 386 amd64p32 arm
netbsd: 386 amd64 arm
openbsd: 386 amd64 arm
plan9: 386 amd64 arm
solaris: amd64
windows: 386 amd64

То есть для сборки кода под Windows мне достаточно сделать GOOS=windows go build. С любой из других архитектур, даже если я собираю это на Raspberry Pi.

jollheef ★★★★★ ()
Последнее исправление: jollheef (всего исправлений: 2)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)