влияние организации файлов на эффективность доступа к файлам

Организация файлов в структуре каталогов может заметно повлиять на эффективность доступа к файлам ( ссылка ). В качестве примера рассмотрим два каталога, A и B , каждый из которых содержит 10 ^ 6 файлов, организованных в одном каталоге в первом случае и в 10 ^ 3 подкаталогах во втором. Подсчет или перечисление всех файлов воспроизводимо медленнее в первом случае. В моей системе:

Создать файлы:

 $ mkdir A; pushd A; seq -w 1E6 | xargs touch; popd $ mkdir B; pushd B; seq -w 1E3 | xargs mkdir; for d in *; do pushd "$d"; seq -w 1E3 | xargs touch; popd; done; popd 

Список файлов:

 $ for d in AB; do time for i in {1..100}; do { echo 3 | sudo tee /proc/sys/vm/drop_caches find "$d" -type f } done >/dev/null done # case A (0 subdirectories) real 4m49.805s user 1m43.696s sys 1m13.540s # case B (1000 subdirectories) real 3m32.338s user 0m40.824s sys 1m13.176s 

Разница воспроизводимая, независимая от кэширования диска и не специфичная для команды find (т. ls -RU Разница той же величины определяется с помощью ls -RU ). Количество времени в пространстве ядра одинаково в обоих случаях, освобождая kernel ​​(и, вероятно, от механики файловой системы). Хотя я не выполнял никакого профилирования, основные системные readdir() почти наверняка readdir() и getdents() и поскольку число inode одинаково в обоих случаях (с точностью до 0,1%), как и размер файлов. количество времени, необходимого для выполнения этих вызовов kernelм, не должно отличаться. Таким образом, разница во времени выполнения связана с кодом пространства пользователя.

Поддержка streamов была добавлена ​​в некоторые ядра GNU (например, sort ). Поскольку в моей системе четыре аппаратных streamа, и я не уверен, что GNU find (версия моей системы 4.7.0-git) была наполнена многопоточными возможностями, я проверил сохранение несоответствия процессам, которые были явно связаны с одним аппаратным streamом. :

 $ cat find.sh #!/bin/bash for i in {1..100}; do { echo 3 | sudo tee /proc/sys/vm/drop_caches find "$1" -type f } done >/dev/null $ for d in AB; do time taskset -c 0 ./find.sh "$d"; done # case A (0 subdirectories) real 4m7.827s user 1m31.080s sys 0m55.660s # case B (1000 subdirectories) real 2m53.059s user 0m33.256s sys 0m52.772s 

Таким образом, мой первоначальный вопрос может быть уточнен следующим образом: каковы неэффективности пользовательского пространства, которые лежат в основе несоответствия во времени доступа, обусловленного исключительно различиями в организации файловой системы? Знание этих недостатков должно позволить лучше реализовать процедуры доступа к файлам.

Редактировать: Я использую файловую систему ext4 на машине с kernelм Linux 4.9.0-4-amd64 , хотя мне было бы интересно узнать, в какой степени ответ зависит от выбранной файловой системы.

Без особых доказательств, я собираюсь догадаться, что find заканчивает тем, что вызывал realloc и копировал данные каталога несколько раз, так как он занимает место в начальном распределении в случае одного каталога. Но в случае нескольких каталогов память, поддерживающая каждое чтение подкаталога, не требует столько копий или перераспределений. Вы можете проверить общее использование памяти для поиска (каким-то образом?), Чтобы проверить.