В частности, меня интересует C++, однако, поскольку Linux написан на C, возможно, C поддерживает этот вариант использования лучше, чем C++.
Следует отметить, что C++ предоставляет как потоковый ввод-вывод, как часть стандартной библиотеки, так и ввод-вывод в стиле C. cppreference
Интересно также отметить, что ввод-вывод файла Rust по умолчанию не буферизуется. Буфера пользовательского пространства не существует, если только пользователь не запрашивает его, обернув файловый ввод-вывод в буферизованный тип чтения или буферизованного записывающего устройства.
По умолчанию потоки ввода-вывода в стиле C и C++ создают как буфер пользовательского пространства, так и буфер ядра. Я предполагаю, что буфер ядра — это встроенная функция ядра, которую нельзя отключить. Цель буфера пользовательского пространства — избежать повторных вызовов ОС всякий раз, когда функция чтения или записи запускается из пользовательского пространства.
Без этого буфера пользовательского пространства каждая операция чтения и записи должна была бы быть системным вызовом, который затрагивает буфер ядра. С помощью буфера пользовательского пространства вызовы чтения и записи могут изменять буфер в памяти, к которому приложение имеет прямой доступ и не требует доступа через ОС, что увеличивает задержку.
Однако недостатком является то, что наличие двух буферов подразумевает, что данные будут копироваться как минимум дважды в рамках любой операции чтения на диск или записи на диск. Таким образом, здесь может быть некоторое снижение производительности, особенно в контексте чтения и записи данных большими блоками.
Итак, пара вопросов.
- Если вам нужно поведение Rust, файловый ввод-вывод без дополнительного буфера пользовательского пространства по умолчанию, что нужно делать?
- С точки зрения ожидаемой производительности, чем это отличается от использования ввода-вывода с отображением в памяти?
Может также помочь, если я объясню, почему я задаю этот вопрос. Мой коллега, похоже, считает, что использование ввода-вывода с отображением в памяти — это волшебное средство для повышения производительности. Однако я не верю в такие волшебные серебряные пули. (К вашему сведению, мой коллега не является экспертом в этой области, он просто так убежден, потому что в прошлом он использовал программу, в которой ввод-вывод с отображением памяти был частью маркетинговых материалов.)
Я предполагаю, что для выполнения блочного ввода-вывода сопоставление памяти вряд ли обеспечит какой-либо значительный выигрыш в производительности при вызове чтения или записи в дескриптор файла, который не имеет дополнительного буфера пользовательского пространства.
Иными словами, если отображение памяти по умолчанию позволяет избежать буфера пользовательского пространства, то если буфер пользовательского пространства можно удалить из операций ввода-вывода, которые по умолчанию будут использовать буфер пользовательского пространства, то почему производительность таких операций не может быть сопоставима с вводом-выводом файла, отображаемого в памяти?
Если вам нужно совершенно конкретное приложение, представьте, что я пишу программу, которая должна читать массив из 10^9 64-битных целых чисел из файла при его запуске, подождите некоторое время для данных для потоковой передачи из сетевого сокета, постепенно добавляйте данные в этот массив в памяти и, прежде чем он выключится, снова запишите этот теперь уже больший массив целых чисел на диск. Почему бы вам не использовать для этого обычные функции чтения и записи, если буфер пользовательского пространства можно отключить?
Подробнее здесь: https://stackoverflow.com/questions/798 ... ers-with-l
Мобильная версия