> Вообще существует ли теоретическое обоснование перевода работ именно в ядро, в смысле,
> какая разница втом, будет ли работой заниматься поток юзера, переключившийся с ядро, или
> юзерспайсовый делегирует всё работу специализированому потоку в пространстве ядра, а сам
> будет ждать уведомлений через поллинг дескрипторов? В солярисе имеется общий принцип:
> "на каждый чих создаём поток ядра". Это оправдано, так как ОС ориентирована на исполнение
> на машинах с сотнями CPU. Но непонятно зачем размножение потоков нужно в freebsb которая
> работает на тазиках с 4-8 CPU. Ну нахватает поток юзерспайсового сервиса запросов не отдачу
> контента, нагрузит работой по сетевому и блочному IO некоторое количество потоков в ядре,
> и те точно так же встанут в взаимных локах и зависнут в конкуренции на доступ к разделяемому
> ресурсу, как заблокировался бы юзерспайcовый поток, на ожидании наполнения кеша address_space в линуксе?Тут есть два заблуждения. Первое, что вообще для ожидания I/O от устройства обязателен какой-то
поток, который будет блокироваться и ждать. Да, именно так часто и делают. Кому-то кажется,
что так проще развязать блокировку - создать под неё поток, который не жалко заблокировать.
Так же сделана и подсистема aio(4) в FreeBSD, в ней есть ядерный aio daemon. Хоть наша AIO
и намного совершеннее, чем в Linux, но мы решили не завязывать новый sendfile на неё. В новом
sendfile не появляется никаких новых потоков или контекстов. На время, когда диск занят копированием
данных из себя в память, никакого контекста нет, который была бы связан непосредственно с этой
операцией.
Второе заблуждение, это про 4-8 CPU. Ну просто какой-то дичайший стереотип. Мол я дома ставлю
FreeBSD поиграться на всякое старьё, наверное и Netflix так делает?! На самом деле нет. Ну просто
возьмите спеки на то поколение машин, где 4-8 кор и поглядите, сможет ли там PCI пропустить
100 Гбит/с.
Что касается ядро-неядро. 15 лет назад была мода всё нести в ядро, мол там быстрее. Теперь появился
netmap и dpdk и в связи с этим новая мода - всё в юзерленд, там быстрее. Ну мебель можно двигать
сколько угодно, а процессор выполняет инструкции с одной скоростью, не важно в каком он сейчас
контексте работает. 15 лет назад смысл переносить функционал в ядро был в том, чтобы избежать
копирования из юзерленд в ядро, а также чтобы уменьшить число переключений контекста, которые
тогда были дорогими. Новая же мода объясняется тем, что ядра обросли функционалом и стали
"подтормаживать на лишних операциях". Поэтому для примитивных задача а ля насрать 50 мегапакетов
в секунду, или же отфильтровать эти же 50 мегапакетов по примитивному критерию, выгоднее стало
писать с нуля сралку или фильтр на dpdk, а операционную систему использовать только для того,
чтобы залогиниться в систему и получить доступ к сетевой карте. Некоторые люди неправильно понимают
этот результат и думают, что если они перенесут весь TCP стек в юзерленд, то он тоже ускорится в
10 раз. Пока успехи на этом поприще достигают только те, кто опять же выполняют очень примитивные
задачи. А как только они доведут свои userland TCP до ума, и по функционалу они будут иметь паритет
с классическими ядерными сокетами, то и производительность выйдет на тот же самый уровень. Ну этот
весь абзац - моё личное мнение. Время покажет, ошибаюсь я или нет.
> В линуксе бликировка на диске в sendfile происходит только на время ожидания поступления данных с
> диска при запуске __blk_run_queue, так как заполнение beffer_head данным осуществляется в потоке,
> сделавшем sendfile. Остальное время поток, сделавший sendfile, не блокируется, а заполняет данными
> address_space файла, и мапит их в буфера pipe-а и исполняет калбек splice_write дескриптора выходного
> сокета. Какая разница, какой поток будет блокироваться на время операции чтения данных с диска, поток
> юзерспайсового сервиса, делающего sendfile, или спецализированного, которому поток юзерпайсового
> сервиса делегирует эту работу?
У нас никакой не блокируется, в этом и соль.