Самый быстрый способ перебора файловой системы - PullRequest
1 голос
/ 06 апреля 2020

Иногда мне нужно рекурсивно пройти по папке, читая содержимое всех файлов внутри.

Я использую C ++ и Linux.

Содержимое папки произвольное, от миллиарда от крошечных файлов до десятка гигантских.

Пытаясь достичь максимальной скорости чтения, я столкнулся с дилеммой. С одной стороны, почти всегда быстрее выполнять все чтение из одного потока, потому что параллельный доступ к файловой системе приводит к перебоям в голове между одновременно читаемыми файлами: enter image description here

На с другой стороны, последовательный доступ к файловой системе из одного потока не такой быстрый, как мог бы быть по двум причинам.

Во-первых, время, прошедшее между завершением предыдущего запроса на чтение и инициированием следующего, составляет потерял. Я стараюсь свести его к минимуму, буквально ничего не делая в потоке чтения, кроме самого чтения, но постоянное переключение между пространством ядра и пользователем все еще некоторое время теряется, особенно в вышеупомянутом случае миллиарды крошечных файлов. enter image description here

Во-вторых, однопоточное чтение не позволяет ядру и / или контроллеру жесткого диска выполнить некоторое переупорядочение запрошенных секторов, что может повысить производительность.

Итак, я хотел бы достичь двух вещей:

1) Например, в LibUsb у меня может быть несколько ожидающих запросов на чтение, которые обрабатываются последовательно , но без паузы между завершением предыдущий запрос и инициирование следующего. Возможно ли получить что-то подобное для доступа к FS?

enter image description here

2) Можно ли одновременно отправить несколько запросов на чтение ядру , , но помечают их каким-либо образом, чтобы ядро ​​знало, что эти запросы не имеют отдельных сроков и что суммарное время их кумулятивного выполнения должно сворачиваться?

enter image description here

1 Ответ

1 голос
/ 08 апреля 2020

Поскольку вы используете Linux, возможно, вам следует попробовать новый интерфейс io_uring . Он заявляет, что он более эффективен и эффективен, чем традиционные синхронные (пул потоков + блокирующие sycalls) или асинхронные libaio подходы.

Для 1 флаг IORING_SETUP_SQPOLL io_uring, кажется, делает то, что вы нужно, пока вы продолжаете прокачивать запросы.

...