Эффекты POSIX_FADV_DONTNEED при вычислении суммы SHA256 с помощью Python (TL;DR не используйте ее)Python

Программы на Python
Ответить Пред. темаСлед. тема
Гость
 Эффекты POSIX_FADV_DONTNEED при вычислении суммы SHA256 с помощью Python (TL;DR не используйте ее)

Сообщение Гость »


Обновление: теперь это больше для документации после проведения большего количества тестов.

TL;DR с использованием POSIX_FADV_DONTNEED того не стоит. Не его использование дает лучшую скорость. На AMD64 это даже похоже не соблюдается.

Вращающийся диск Rasperry PI4 USB 3.0 емкостью 5 ТБ с файловой системой ext4

Использование 1 потока с этой конфигурацией обеспечивает наилучшую скорость, возможно, из-за вращающегося диска.

При вычислении суммы SHA256 всех файлов в дереве каталогов (проверка нескольких репозиториев Restic без необходимости ввода пароля шифрования для каждого репозитория) скорость чтения диска отображается в nmon, а с помощью node_exporter скорость почти в два раза выше, чем при используя POSIX_FADV_DONTNEED. Этот аргумент сообщает ядру не хранить данные в кеше. Это имеет смысл, поскольку эти файлы считываются только один раз и в противном случае загрязнили бы кэш системы и, таким образом, замедлили бы ее работу, поскольку другие данные не были бы в кэше.

Без POSIX_FADV_DONTNEED скорость чтения составляет от 60 до 90 МБ/с. При использовании POSIX_FADV_DONTNEED скорость чтения составляет от 155 МБ/с до 175 МБ/с, то есть примерно в два раза выше скорости. Это значение отображается в nmon и prometheus node_exporter в сочетании с VictoriaMetrics. Однако использование команды time дает совершенно другие результаты. Между каждым запуском происходила синхронизация ; echo 3 > /proc/sys/vm/drop_caches

При использовании posix_fadvise(fd, 0, bytesRead) время составляло 37 секунд и отображалась низкая скорость диска. При использовании posix_fadvise(fd, 0, 0) отображалась скорость диска примерно в два раза, но на самом деле время составляло 1m8 секунд. При использовании

def posix_fadvise(fd, offset, length): возвращаться только 29 там, где это необходимо, поэтому самые быстрые результаты были достигнуты без использования POSIX_FADV_DONTNEED вообще.

Итак, на Raspberry-Pi отображается неверная скорость диска, тогда как на AMD64 отображается более точная скорость. В Raspberry PI вы можете видеть в VictoriaMectrics и размере кэша, что он не увеличивается при использовании POSIX_FADV_DONTNEED, поэтому этот флаг соблюдается.

РЕДАКТИРОВАТЬ: На размещенной виртуальной машине с SSD и гораздо большей производительностью даже при использовании 4 потоков использование POSIX_FADV_DONTNEED делает воспроизводимость примерно в 5 раз медленнее. Между каждым запуском я делал # echo 3 > /proc/sys/vm/drop_caches Очень странно.

EDIT2: На физическом хосте с использованием вращающегося диска, подключенного через USB3.0 и 1 поток, при использовании POSIX_FADV_DONTNEED чтение всех файлов занимает 1 мин 25 с. После очистки кеша с помощью # echo 3 > /proc/sys/vm/drop_caches и без использования POSIX_FADV_DONTNEED вычисление контрольной суммы занимает всего 12 секунд. То есть разница в 7 (!) раз.

Обновление от 20.09.2023: С помощью VictoriaMectrics я вижу, что POSIX_FADV_DONTNEED, похоже, не соблюдается в отношении кеша на AMD64 (на RPi это так, см. выше), вы можете видеть, как он растет, несмотря на установку флаг. Нет заметной разницы в скорости (при использовании команды time) при использовании posix_fadvise(fd, 0, bytesRead) (реальный пользователь 1m53,630s 0m48,819s sys 0m5,627s) и немедленно возвращаемся в def posix_fadvise(fd, offset, length): (реальный пользователь 1m52,675s 0m51,346s sys 0m6,928s). Использование posix_fadvise(fd, 0, 0) занимает реальные 2 м31 398 с, пользователь 1 м 2 004 с sys 0 м 16 178 с
импортировать ОС подпроцесс импорта импортировать хеш-библиотеку импортировать concurrent.futures импортировать систему импорт типов # Константы для posix_fadvise POSIX_FADV_DONTNEED = 4 base_directory = '/home/pi/5TB' num_threads = 1 # Отрегулируйте количество потоков по мере необходимости # Определить функцию posix_fadvise def posix_fadvise(fd, offset, length): #return #uncomment и скорость будет намного медленнее libc = ctypes.CDLL("libc.so.6") ret = libc.posix_fadvise(fd, offset, length, POSIX_FADV_DONTNEED) если возврат != 0: поднять OSError(f"posix_fadvise не удалось с кодом ошибки {ret}") защита вычисление_sha256 (путь_файла): пытаться: # Вычисляем контрольную сумму SHA256 файла sha256_hash = hashlib.sha256() bytesRead = 0 # Инициализируем счетчик прочитанных байт с open(file_path, 'rb') как f: fd = f.fileno() # Получить дескриптор файла # Сообщите ядру, что данные файла нам больше не нужны #posix_fadvise(fd, 0, 0) пока правда: data = f.read(65536) # Чтение кусками по 64 КБ если нет данных: перерыв bytesRead += len(данные) sha256_hash.update(данные) posix_fadvise(fd, 0, bytesRead) контрольная сумма = sha256_hash.hexdigest() # Проверяем, соответствует ли контрольная сумма имени файла имя_файла = os.path.basename(путь_файла) если контрольная сумма != имя файла: sys.stderr.write(f"Ошибка: несоответствие контрольной суммы для файла '{file_path}'\n") вернуть путь_файла кроме исключения как e: sys.stderr.write(f"Ошибка обработки файла '{file_path}': {str(e)}\n") возврат Нет Защиту процесс_файлы_в_каталоге (каталог): files = [os.path.join(каталог, имя файла) для имени файла в os.listdir(каталог), если os.path.isfile(os.path.join(каталог, имя файла))] результаты = [] с concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) в качестве исполнителя: для файла в executor.map(calculate_sha256, files): если файл не None: результаты.append(файл) вернуть результаты если __name__ == "__main__": проверенный_счет = 0 для root, _, _ в os.walk(base_directory): проверенные_файлы = процесс_файлы_в_каталоге (корневой) проверенный_счет += len(проверенные_файлы) если проверено_счет % 100 == 0: sys.stdout.write(f"Проверено {checked_count} файлов...\n") sys.stdout.flush() # Очищаем буфер стандартного вывода для немедленной записи sys.stdout.write(f"Всего проверено {checked_count} файлов.\n")
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ, комментарий, отзыв

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»