Я заметил странную проблему при тестировании произвольного чтения ввода-вывода для файлов в linux (2.6.18). Программа Benchmarking - это моя собственная программа, и она просто продолжает читать 16 КБ файла со случайным смещением.
Я отследил поведение ввода-вывода на уровне системного вызова и уровне scsi с помощью systemtap и заметил, что один 16KB sysread выдает 2 ввода-вывода scsi, как показано ниже.
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 128137183232
SCSI random(8472) 0 1 0 0 start-sector: 226321183 size: 4096 bufflen 4096 FROM_DEVICE 1354354008068009
SCSI random(8472) 0 1 0 0 start-sector: 226323431 size: 16384 bufflen 16384 FROM_DEVICE 1354354008075927
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 21807710208
SCSI random(8472) 0 1 0 0 start-sector: 1889888935 size: 4096 bufflen 4096 FROM_DEVICE 1354354008085128
SCSI random(8472) 0 1 0 0 start-sector: 1889891823 size: 16384 bufflen 16384 FROM_DEVICE 1354354008097161
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 139365318656
SCSI random(8472) 0 1 0 0 start-sector: 254092663 size: 4096 bufflen 4096 FROM_DEVICE 1354354008100633
SCSI random(8472) 0 1 0 0 start-sector: 254094879 size: 16384 bufflen 16384 FROM_DEVICE 1354354008111723
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 60304424960
SCSI random(8472) 0 1 0 0 start-sector: 58119807 size: 4096 bufflen 4096 FROM_DEVICE 1354354008120469
SCSI random(8472) 0 1 0 0 start-sector: 58125415 size: 16384 bufflen 16384 FROM_DEVICE 1354354008126343
Как показано выше, один преад 16 Кбайт выполняет 2 ввода-вывода scsi. (Я отслеживал отправку scsi io с помощью probe scsi.iodispatching. Пожалуйста, игнорируйте значения, кроме начального сектора и размера.)
Один ввод-вывод scsi - это ввод-вывод 16 Кбайт по запросу из приложения, и все в порядке. Дело в другом вводе-выводе 4 КБ, и я не знаю, почему Linux выдает этот ввод-вывод.
Конечно, производительность ввода-вывода снижается из-за устаревшего ввода-вывода 4 КБ, и у меня проблемы. Я также использую fio (известный инструмент для тестирования ввода-вывода) и заметил ту же проблему, так что это не из приложения.
Кто-нибудь может мне это объяснить?
Это может быть глупая / очевидная вещь, которую вы уже проверили, но смонтирована ли ваша файловая система с noatime
флаг?
Если вы не указали noatime
тогда Linux необходимо обновлять индексный дескриптор каждый раз при обращении к файлу (чтобы установить адоступ время), что означает, что он должен прочитать область диска, содержащую индексный дескриптор, и записать ее обратно. (Кстати, именно поэтому критичные к производительности файловые системы с интенсивным чтением должны монтироваться с noatime
- ввод / вывод для постоянного обновления inodes значительный и может быть ощутимым падением производительности).
Я понял. Это от косвенного блочного отображения ext3. (В Ext3 есть блок, который содержит указатели блоков в каждых 1024 блоках.)
Я изменил файловую систему на ext4, проблема исчезла. (Ext4 имеет более эффективную схему адресации блоков.)
Спасибо вам всем.
Я понял, что происходит, но не знаю, для чего это нужно.
Файловая система Ext3 имеет несколько 4 КБ данных в каждом 4096 КБ (8192 сектора) данных. Визуально данные выравниваются следующим образом.
| 4KB | 4096KB | 4KB | 4096KB | 4KB | 4096KB | ...
И область 4096 КБ доступна только для прикладных программ. При первом доступе к первой области 4096 КБ ОС сначала считывает 4 КБ непосредственно перед областью 4096 КБ, а затем считывает запрошенные данные в области 4096 КБ.
При доступе к большому файлу (по сравнению с размером DRAM) случайным образом каждый ввод-вывод имеет редкую вероятность попадания на страницу cahce, поэтому каждый запрос ввода-вывода сопровождается вводом-выводом 4 КБ.
Дело в том, для чего нужны данные 4 КБ? Это метаданные местоположения для файловой системы? Есть ли способ удалить это? Или есть ли способ очистить только область 4096 КБ?
Любые комментарии и советы приветствуются.
(Я тестировал на многих машинах со многими версиями ядра. Это происходит на всех машинах.)
Спасибо.