Действительно ли в Linux нет асинхронного блочного ввода-вывода?

Рассмотрим приложение, которое связано с центральным процессором, но также имеет высокопроизводительные требования к вводу / выводу.

Я сравниваю файловый ввод / вывод Linux с Windows, и я не вижу, как epoll вообще поможет программе Linux. Ядро скажет мне, что файловый дескриптор «готов к чтению», но мне все еще нужно вызвать блокировку read (), чтобы получить мои данные, и если я хочу прочитать мегабайты, то довольно ясно, что это заблокирует.

В Windows я могу создать дескриптор файла с установленным значением OVERLAPPED, а затем использовать неблокирующий ввод-вывод, получать уведомления о завершении ввода-вывода и использовать данные из этой функции завершения. Мне не нужно тратить время на ожидание данных на уровне приложения, а это означает, что я могу точно настроить количество потоков на количество ядер и получить 100% эффективное использование процессора.

Если мне нужно эмулировать асинхронный ввод-вывод в Linux, то для этого мне нужно выделить некоторое количество потоков, и эти потоки будут тратить немного времени на выполнение задач ЦП и много времени на блокировку ввода-вывода, Кроме того, в обмене сообщениями с этими потоками будут накладные расходы. Таким образом, я буду либо переподписываться, либо недоиспользовать свои ядра процессора.

Я смотрел на mmap () + madvise () (WILLNEED) как на «асинхронный ввод-вывод бедняка», но он все еще не дошел до конца, потому что я не могу получить уведомление, когда это будет сделано - у меня есть «угадать» и, если я угадал «неправильно», я в конечном итоге заблокирую доступ к памяти, ожидая поступления данных с диска.

Похоже, что в Linux есть запуск асинхронного ввода-вывода в io_submit, и, похоже, также есть реализация POSIX aio в пользовательском пространстве, но это уже давно, и я не знаю никого, кто бы поручился за эти системы за критическую высокопроизводительные приложения.

Модель Windows работает примерно так:

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

Шаги 1/2 обычно выполняются как одно целое. Шаги 3/4 обычно выполняются с пулом рабочих потоков, а не (обязательно) с тем же потоком, что и ввод-вывод. Эта модель в некоторой степени похожа на модель, предоставляемую boost :: asio, за исключением того, что boost :: asio фактически не обеспечивает асинхронный блочный (дисковый) ввод-вывод.

Отличие от epoll в Linux состоит в том, что на шаге 4 еще не произошло ввода-вывода - он поднимает шаг 1, чтобы идти после шага 4, который является «задом наперед», если вы точно знаете, что вам уже нужно.

Запрограммировав большое количество встроенных, настольных и серверных операционных систем, я могу сказать, что эта модель асинхронного ввода-вывода очень естественна для определенных видов программ. Это также очень высокая пропускная способность и низкие накладные расходы. Я думаю, что это один из оставшихся реальных недостатков модели ввода-вывода Linux на уровне API.

Ответы на вопрос(3)

Ваш ответ на вопрос