Який статус POSIX асинхронного вводу / виводу (AIO)?


93

Існують сторінки, розкидані по Інтернету, які описують засоби POSIX AIO з різною кількістю деталей. Жоден з них не є жахливо останнім часом. Не ясно, що саме вони описують. Наприклад, "офіційний" (?) Веб-сайт для асинхронної введення-виводу ядра Linux тут говорить про те, що сокети не працюють, але сторінки керівництва "aio.h" на моїй робочій станції Ubuntu 8.04.1, мабуть, означають, що він працює для довільних дескрипторів файлів. Потім є ще один проект, який, здається, працює на рівні бібліотеки з ще меншою кількістю документації.

Я хотів би знати:

  • Яка мета POSIX AIO? Зважаючи на те, що найочевидніший приклад реалізації, який я можу знайти, говорить про те, що він не підтримує сокети, все це мені здається дивним. Це тільки для вводу / виводу диска async? Якщо так, навіщо гіпер-загальний API? Якщо ні, то чому введення / виведення диска - перше, на що напали?
  • Де є приклади повних програм POSIX AIO, які я можу переглянути?
  • Хтось насправді ним користується, по-справжньому?
  • Які платформи підтримують POSIX AIO? Які його частини вони підтримують? Хтось насправді підтримує мається на увазі "Будь-який I / O для будь-якого FD", який, <aio.h>здається, обіцяє?

Інші доступні мені механізми мультиплексування є ідеально гарними, але випадкові фрагменти інформації, що пливуть там, викликали цікавість.

Відповіді:


27

Мережевий введення / вивід не є пріоритетним для AIO, оскільки кожен, хто пише мережеві сервери POSIX, використовує підхід, не блокуючий події. Старий стиль Java "мільярди блокуючих ниток" жахливо смокче.

Введення / виведення запису диска вже буферизоване, а введення / виведення зчитування диска можна попередньо встановити в буфер за допомогою таких функцій, як posix_fadvise. Це залишає прямий, незаблокований вхід / вивід диска як єдину корисну мету для AIO.

Прямий, нерозподілений введення / вивід є дійсно корисним лише для транзакційних баз даних, і ті, як правило, записують власні потоки або процеси для управління дисковими введеннями / виводами.

Отже, врешті-решт, це залишає POSIX AIO в положенні не служити ніякій корисній меті. Не використовуйте його.


8
А як щодо читання / запису з мережевих файлових систем (NFS, Samba)?
Алекс Б

1
Ну. У мене є кілька великих німих письменників, які, якщо я відпущу їх у кеш, потраплять на брудний рівень на піках, блокуючи всіх інших. Якщо я просто використовую прямий IO на них, це занадто повільно. Якби у мене був лише один потік, я міг би самостійно керувати, але важко буде підтримувати різні пріоритети введення-виводу за 1 протектор. Вулики AIO + CFQ справді здаються гарною комбінацією, якщо AIO працював
n-alexander

37
Я не погоджуюсь. Введення / виведення диска, як правило, буферизоване, але може блокувати. При опитуванні файлу FD він завжди повідомляє, що FD читається, навіть коли він блокується. Це унеможливлює рівномірне виконання неблокуючих операцій над файлами диска, якщо тільки не використовуються потоки або AIO.
Гонлі

2
@Matt: Порядок не важливий для розеток дейтаграми. @Zan: введення / виведення async дуже приємно для попереднього запуску потокової передачі даних у реальному часі, наприклад, медіаплеєри.
Бен Войгт

13
Неправда, що AIO марний у системах, що базуються на подіях. Насправді ви можете дістатись до нульових копій мереж за допомогою належного AIO, чого ви не можете, якщо ви бачите події на recv (). Інші речі можуть скласти змову, щоб зробити це здебільшого теоретичним обмеженням, але я думаю, що відсутність належного AIO (a la OVERLAPPED в Windows) є однією з останніх великих дірок в Linux.
Джон Ватт

69

Ефективне введення / виведення сокета вирішено за допомогою kqueue, epoll, портів для завершення IO тощо. Асинхронний файл вводу / виводу є своєрідним пізнім (крім перекритого вікном вводу / виводу та ранньої підтримки для posix AIO).

Якщо ви шукаєте робити введення / виведення сокета, вам, мабуть, краще скористатися одним із перерахованих вище механізмів.

Основна мета AIO - отже, вирішити проблему асинхронного дискового вводу / виводу. Це, швидше за все, тому Mac OS X підтримує лише AIO для звичайних файлів, а не сокетів (оскільки kqueue все одно робить це набагато краще).

Операції запису, як правило, кешуються ядром і видаляються пізніше. Наприклад, коли зчитувана головка накопичувача проходить повз місце, де слід записувати блок.

Однак для операцій з читанням, якщо ви хочете, щоб ядро ​​надало пріоритет і замовляло свої зчитування, AIO - це справді єдиний варіант. Ось чому ядро ​​може (теоретично) зробити це краще, ніж будь-яке додаток на рівні користувача:

  • Ядро бачить усі дискові введення / виведення, а не тільки ваші завдання на диску, і може замовити їх на глобальному рівні
  • Ядро (можливо) знає, де знаходиться головка зчитування диска, і може вибирати завдання для читання, які ви передаєте йому, в оптимальному порядку, щоб перемістити голову на найкоротші відстані
  • Ядро може скористатися натурною чергою команд, щоб додатково оптимізувати свої операції зчитування
  • Можливо, ви зможете здійснити більше операцій зчитування за системний виклик за допомогою lio_listio (), ніж для readv (), особливо якщо ваші читання не є (логічно) суміжними, зберігаючи крихітний біт накладних системних викликів.
  • Ваша програма може бути трохи простішою з AIO, оскільки вам не потрібна додаткова нитка для блокування дзвінка читання або запису.

Однак, posix AIO має досить незручний інтерфейс, наприклад:

  • Єдиним ефективним та добре підтримуваним способом зворотних викликів подій є сигнали, що ускладнює їх використання в бібліотеці, оскільки це означає використання сигнальних номерів з просторового простору імен сигналів процесу. Якщо ваша ОС не підтримує сигнали в режимі реального часу, це також означає, що вам доведеться переглядати всі свої непогашені запити, щоб з'ясувати, який з них фактично закінчений (це стосується, наприклад, Mac OS X, а не Linux). Ловля сигналів у багатопотоковому середовищі також передбачає деякі складні обмеження. Зазвичай ви не можете реагувати на подію всередині обробника сигналів, але вам потрібно підняти сигнал, записати в трубку або використовувати signalfd () (на Linux).
  • lio_suspend () має ті самі проблеми, що і select (), але він не дуже добре розширюється з кількістю завдань.
  • lio_listio (), оскільки впроваджена має досить обмежену кількість завдань, які ви можете передати, і не тривіально знайти цю межу портативно. Вам потрібно зателефонувати на sysconf (_SC_AIO_LISTIO_MAX), який може не вдатися, і в цьому випадку ви можете використовувати визначення AIO_LISTIO_MAX, які не обов'язково визначаються, але тоді ви можете використовувати 2, які визначаються як гарантовано підтримувані.

Що стосується додатків у реальному світі, що використовують posix AIO, ви можете поглянути на lighttpd (lighty), який також розмістив вимірювання продуктивності при впровадженні підтримки.

На сьогоднішній день більшість платформ Posix підтримує posix AIO (Linux, BSD, Solaris, AIX, tru64). Windows підтримує його через перекритий файл вводу-виводу. Я розумію, що лише Solaris, Windows та Linux справді підтримують асинхронізацію. файли вводу / виводу до самого драйвера, тоді як інші ОС наслідують асинхронізацію. Введення / виведення з потоками ядра. Винятком є ​​Linux, його реалізація posix AIO у glibc емулює операції async з потоками користувачів, тоді як його вбудований інтерфейс вводу / виводу async (io_submit () тощо) є справді асинхронним аж до драйвера, припускаючи, що драйвер підтримує його .

Я вважаю, що досить часто серед ОС працює не підтримувати позікс AIO для будь-якого fd, а обмежувати його звичайними файлами.


У Windows вперше з'явилися файли, що підтримують диски, які підтримують введення / виведення. Це зовсім не нове. І на POSIX, простір імен сигналів не є глобальним процесом, це за нитку. Сигнали доставляються до певних потоків (або це виняток із цього, не можете згадати напевно?).
Бен Войгт

1
Немає можливості визначити, до якого потоку AIO надсилає свої сигнали. У Linux це, здається, здебільшого доставляє його до потоку, який видав команду aio _ * (), але не завжди (єдине я знайшов для цього рішення - створити декілька сигнальних файлів). У списку розсилки ядра кілька років тому з'явився патч Linux, який додав би це, але він ніколи не робив це, і це було б розширенням для POSIX. У Mac OS X сигнали, здається, в основному надходять до головної нитки (на мій досвід). Я не думаю, що POSIX вимагає конкретної поведінки, якщо це так, я хотів би побачити частину специфікації.
Арвід

5
Реалізація ali_read / write glibc використовує потоки в userland, тому тут не використовуються навіть нитки ядра.
Маренц

Що означає "завжди типово"? Записи кешовані ядром для будь-якого методу або при використанні AIO? Здається, що повинен існувати спосіб впевнитися в тому, що запис було успішно завершено; інакше цілісність та цілі транзакцій не можуть бути досягнуті.
МайкБ

Інший живий приклад, де можна використовувати AIO, - nginx. Всі режими підтримуються. Якщо ви віддаєте перевагу вивантаженню в потоки користувача, ви, як правило, вважаєте, що це набагато гірше, ніж прямий IO, але нативний AIO Linux знаходиться нарівні з прямим IO. Ситуація, коли AIO може бути корисною, - це сильний тиск у кеші сторінки. Концептуальна різниця між Async та Direct IO можна побачити тут ftp.dei.uc.pt/pub/linux/kernel/people/suparna/aio-linux.pdf
wick


2

Є aio_write - реалізований у glibc; Перший виклик функції aio_read або aio_write породжує ряд потоків користувальницького режиму, aio_write або aio_read запитів до цього потоку, потік робить попередньо / pwrite і після завершення відповідь надсилається назад до заблокованого потоку виклику.

Ther також "справжній" aio - підтримується рівнем ядра (для цього потрібна libaio, див. Виклик io_submit http://linux.die.net/man/2/io_submit ); для цього також потрібен O_DIRECT (також може підтримуватися не всіма файловими системами, але основні підтримують його)

дивіться тут:

http://lse.sourceforge.net/io/aio.html

http://linux.die.net/man/2/io_submit

Відмінність POSIX AIO від libaio в Linux?


Багато недоліків aio_writeвисвітлено вище, у stackoverflow.com/a/5307557/13564
Glyph
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.