tgoop.com/reverse13/672
Last Update:
1) Пишем write
в буфер фиксированного размера
2.1) Периодически флашим его, то есть асинхронно отправляем write
c буффером через io_uring
интерфейс (тут также понадобится некоторый кеш блоков, так как мы отдаем владение блоком ядру, но это просто список, стек)
2.2) Тут возможна оптимизация, есть два варианта как пользоваться io_uring
сабмитить данные самому через сискол, или завести специальный поток на стороне ядра который будет поллить очередь [3].3) Когда же попросили сделать fsync
, мы просто флашим буфер, и хочется сказать "отправляем fsync
через io_uring
", но нет, ведь ядро, может исполнять запросы в очереди в произвольном порядке, что и делает io_uring
действительно быстрым (забавно кстати, что есть некоторые параллели с тем как vulkan
отличается от opengl
). То есть, если мы просто будем отправлять fsync
, то ядро сначала может исполнить его, а затем уже write
-ы которые в очереди.
3) Что же тогда делать? Ну можно было бы дождаться завершения всех вызовов в очереди, то есть самим по-poll-ить completion queue, но есть решения лучше, давайте просто запушим nop
операцию которая будет с DRAIN
флагом, такая операция и будет барьером, который не позволит ядру запустить fsync
раньше чем исполнить все write
, при этом мы не будем ждать (!)
Собственно все, задача решена, самое приятное с точки зрения файлового IO, что все это работает как с буферезованным, так и с нет IO, например никто не мешает использовать mmap
файла для рандомных чтений.
Ну и как вишенка на торте, то что помимо правильного API мы получаем самое производительное решение: есть разные бенчмарки, вот например [5]
Пожалуй единственный печальный момент, что даже 5.1 кернел еще далеко не у всех юзеров, как я понимаю enterprise на данный момент это в основном 3-4 кернелы (что конечно пиздец, но спасибо хоть не 2)
Что же с аналогами не из мира linux?
Ну на Windows, довольно быстро сообразили, что тут сделали офигенную штуку и сделали аналог [6], судя по тому, что я видел, разница около косметическая, что если WIndows это уже давно, просто лишняя абстракция над Linux кернелом? Работает же WSL как-то, ощущения что буквально взяли почти как есть io_uring
.
Из особенностей, помимо мелких отличий, оно более свежее, так что мануалов, багов и тд, наверно больше. А еще, помоему, нет некоторых фичей, но задел под флаги есть [7], так что думаю это только вопрос времени.
В FreeBSD
, macOS
, ... ну вы поняли, насколько я знаю аналога нет :(
Ну пожалуй стоит заметить, что kqueue
изначально сделан более прямо чем epoll
и умеет в fd
в отличии от него (epoll
всегда возвращает что готов)
Как следствие проблема именно файлового IO там вероятно чуть менее остра? Ну а сокращение количества вызовов сисколов (только сейчас задумался как же странно это звучит), и возможность делать асинхронными не только read/write видимо менее критична на их взгляд. Не знаю, вообще macOS закрытая, а FreeBSD полутруп?
Но говоря про последнее, меня очень привлекает в io_uring
именно возможность удешевления сисколов до почти обычных вызовов [8].
Может кто знает, я не интересовался такими маргинальными знаниями раньше: похоже ли io_uring
на то, как обычно делают взаимодействие между компонентами в микроядерных ОС?
Но ладно, это неважно, важно, как мне кажется, то что по мере добавления поддержки новых сисколов в io_uring
, возможно из Linux-а вынесут к черту большую часть кернел имплемнатции дров? И будет в кернеле не 20+ млн строк, а хотя бы какая-нибудь парочка)
Ладно оставим эти влажные фантазии, надеюсь на какую-то активность в комментах, я старался, а io_uring
классный
Ну и за рамками обсуждения осталось, то что никто не мешает прикрутить io_uring
к сокетам и посоревноваться с epoll
, но учитывая, что последний итак хорошо работает, как по мне это уже не так интересно.
BY Loser story
Share with your friend now:
tgoop.com/reverse13/672