Существуют ли общепринятые рекомендации для достижения максимально быстрого последовательного файлового ввода-вывода в C ++?
Правило 0: Мера. Используйте все доступные инструменты профилирования и познакомьтесь с ними. Это почти заповедь в программировании, что если вы не измеряли это, вы не знаете, насколько это быстро, а для ввода / вывода это еще более верно. Обязательно проведите тестирование при фактических условиях работы , если возможно. Процесс, который не конкурирует за систему ввода / вывода, может быть чрезмерно оптимизирован, настроен для условий, которые не существуют при реальных нагрузках.
Используйте отображенную память вместо записи в файлы. Это не всегда быстрее, но дает возможность оптимизировать ввод-вывод специфичным для операционной системы, но относительно переносимым способом, избегая ненужного копирования и используя знания ОС о том, как на самом деле используется диск. («Переносимый», если вы используете оболочку, а не вызов API для конкретной ОС).
Попробуйте и линеаризовать ваш вывод как можно больше. Необходимость перепрыгивать память, чтобы найти буферы для записи, может иметь заметные эффекты при оптимизированных условиях, потому что строки кеша, разбиение на страницы и другие проблемы подсистемы памяти начнут иметь значение. Если у вас много буферов, посмотрите на поддержку ввода-вывода с разбросом , которая пытается сделать это линеаризацией для вас.
Некоторые возможные соображения:
- Рекомендации по выбору оптимального размера буфера
Размер страницы для начинающих, но будьте готовы к настройке оттуда.
- Будет ли переносимая библиотека типа boost :: asio слишком абстрагированной, чтобы раскрывать тонкости
конкретной платформы, или их можно считать оптимальными?
Не думайте, что это оптимально. Это зависит от того, насколько тщательно библиотека работает на вашей платформе, и от того, сколько усилий разработчики приложили для ее ускорения. Сказав, что переносимая библиотека ввода-вывода может быть очень быстрой, потому что быстрые абстракции существуют в большинстве систем, и обычно можно придумать общий API, который охватывает множество основ. Насколько мне известно, Boost.Asio достаточно хорошо настроен для конкретной платформы: для быстрого асинхронного ввода-вывода существует целое семейство API-интерфейсов для конкретных ОС и вариантов ОС (например, epoll * 1040). *, / dev / epoll , kqueue , Windows перекрывает ввод-вывод ), и Asio оборачивает их всех.
- Всегда ли асинхронный ввод-вывод предпочтительнее синхронного? Что если приложение не связано с другими процессорами?
Асинхронный ввод-вывод не является быстрым в необработанном смысле, чем синхронный ввод-вывод. Что делает асинхронный ввод-вывод, так это гарантирует, что ваш код не тратит время на ожидание завершения ввода-вывода. В общем, это быстрее, чем другой метод не тратить это время, а именно, используя потоки, потому что он обратится к вашему коду, когда ввод-вывод будет готов, а не раньше. Нет никаких фальстартов или проблем с незанятыми потоками, которые необходимо прервать.