Как стать автором
Обновить

Измерение скорости чтения-записи носителей с помощью утилиты dd

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 12K
Всего голосов 61: ↑59 и ↓2 +57
Комментарии 45

Комментарии 45

Не знаю сколько автору годков, но лет 15 назад так измеряли скорость дисков.

Вроде это делали с помощью hdparm -t. По крайней мере для чтения.

Для таких целей надо использовать fio. Работает на всём и делает то что надо.

Спасибо за наводку. Интересно, как он оценивает работу таких носителей, как NAND-память?

Прям с удовольствием почитал маны https://fio.readthedocs.io/en/latest/fio_doc.html . Достоинство dd только одно: по умолчанию есть в системе, и не надо ничего собирать. В остальном одни недостатки.

Точно, точно, про mtd-utils я и забыл.

Эта статья на Хабре возможно и была моим первым знакомством с fio. Уже не помню, но по времени совпадает 🤔

А самое главное, дд измерит только последовательные операции. Для обычной работы (н-р сервер или рабочая станция) от этого ни тепло, ни холодно.

Для SSD-диска это не очень принципиально. А вот для обычных дисков, да, критично. При этом если данные сильно разбросаны, то скорости могут меняться в больших пределах.

Лучше на English. Русский перевод часто опаздывает.
https://wiki.archlinux.org/title/Benchmarking
The dd utility can be used to measure both reads and writes. This method is dependent on partition alignment!
https://wiki.archlinux.org/title/Advanced_Format#Partition_alignment
See dd-benchmark for an explanation on the requirement to sync and further related dd options.
How to use 'dd' to benchmark your disk or CPU?
https://romanrm.net/dd-benchmark

Большое спасибо за ссылки и дополнения!

Запуск с ключами oflag=direct,sync разве не покажет реальную производительность диска?

По идее должно. Но на деле у меня отличались данные, чем вот используя sync в конце. Да и в этой статье рекомендуется делать так как делаю я. Но вы правы, это тоже должно работать.

Настаиваю на прогоне с oflag=direct и однобайтовой записи из введения.

На линухе достаточно просто flag=direct. На фре conv=sync обязателен, иначе хвост файла окажется недописанным.

Только не спутать flag, iflag и oflag :)

Одни сплошные нюансы. :)

Лет 20 назад я скорость чтения мерил дос навигатором путём копирования большого файла в NUL

Мерять скорость записи на флеш при помощи одних нулей может оказаться измерением ничего. Например, видя, что все байты -- нули, контроллер вполне может просто вносить изменение в таблицу соответствия блоков, представляемых для компьютера и реальных секторов flash-микросхемы таким образом, чтобы их просто "раз'map'ить", по аналогии с trim/discard.

Да, это очень правильное замечание. В идеале измерять надо тремя параметрами:

1. Нули.
2. 0xFF
3. Случайные данные.

Вообще, реальная задача измерения скорости диска будет сложнее, чем просто писать данные с помощью dd.

Только поблочно случайные данные, чтобы не схватить эффект дедупликации, который отсечется непонятно кем и на каком уровне. Было загадочно, не весело, долго, но до сути докопался.

Контроллер: SMI SM2262EN / SMI SM2262

Почему: бракованная флеш-память, которую пока не тронешь - вонять не станет.

Второе: не доверять забиванию нулей, в смысле не отождествлять это с TRIM/Overprovisioning. Лучше сбросить контроллером всю память и неиспользованное разметить. Потому что непонятно, что там код текущей ревизии какого-то производителя делает.

Случайные данные тоже могут содержать массив нулей. Поэтому надо контролировать такое.

Могут, но не будут :) Если мы говорим про массив больше чем из 4 байт.

if=/dev/urandom спасет отцов русской демократии. Правда таким способом вы еще за одно проведете измерение скорости работы ядренного генератора случайных чисел. :-) Но его можно легко вычесть.

На моём ноутбуке с Ryzen5 фря дает следующие цифры:

rz@butterfly:~ % dd if=/dev/urandom of=/dev/null bs=81920 status=progress
2515435520 bytes (2515 MB, 2399 MiB) transferred 6.003s, 419 MB/s

rz@butterfly:~ % dd if=/dev/zero of=/dev/null bs=81920 status=progress
134163005440 bytes (134 GB, 125 GiB) transferred 3.003s, 45 GB/s

rz@butterfly:~ % dd if=/dev/nvd0 of=/dev/null status=progress bs=81920 iflag=direct
14132428800 bytes (14 GB, 13 GiB) transferred 39.002s, 362 MB/s

Записать выхлоп urandom на ramdisc;

Ramdisc -> dd

Profit!

В общем-то, наверное достаточно просто записать в /tmp, на фре это диск в памяти.

И в таких случаях надо следить, чтоб рамдиск в своп не выплеснулся

Свопы - пережиток прошлого, сейчас уже ни у кого их нет. :)

После чего на быстром ssd получится, что вы меряете скорость генерации рандома а не скорость записи :)

Тут уже предложили решение - записать рандом на ramdisk или в файл в /tmp и уже с него писать на SSD.

PS: А быстрый SSD это сколько ? Я вот свои диски промерил и что-то как-то приугас - ~400МБ/сек максимум что есть.

Проще уже взять fio, где можно подогнать распределение под реальную нагрузку.

А причина достаточно простая, жёсткий диск — это блочное устройство и работа с ним ведётся блоками данных. Если вы читаете или пишете (как в случае выше) 1 байт, вы всё равно записываете блок данных, который больше 1 байта, а может быть размером от 512 и более байт, которое кратно 512 байтам.

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

$ mount | grep '/tmpfs'
tmpfs on /tmpfs type tmpfs (rw,relatime,size=10485760k,inode64)

$ time $(dd if=/dev/zero of=/tmpfs/test.raw bs=1 count=1M && sync)
1048576+0 records in
1048576+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.4183 s, 2.5 MB/s

real	0m0.429s
user	0m0.088s
sys	0m0.334s

$ time $(dd if=/dev/zero of=/tmpfs/test.raw bs=1M count=1 && sync)
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00184073 s, 570 MB/s

real	0m0.019s
user	0m0.000s
sys	0m0.010s

Спасибо за дополнение.

Почему бы не воспользоваться для измерения скорости диска специально предназначенной для этого утилитой? hdparm -Tt /dev/sda

К сожалению, причины две:
1. Не на всех системах она установлена.
2. Далеко не всегда носители это устройства SATA/IDE. Скорее, чаще не они.

Дополню цитатой из мана по утилите:

HDPARM(8)                                                                                               System Manager's Manual                                                                                              HDPARM(8)


NAME

      hdparm - get/set SATA/IDE device parameters


SYNOPSIS

      hdparm [options] [device ...]


DESCRIPTION

      hdparm  provides  a  command line interface to various kernel interfaces supported by the Linux SATA/PATA/SAS "libata" subsystem and the older IDE driver subsystem.  Many newer (2008 and later) USB drive enclosures now also

      support "SAT" (SCSI-ATA Command Translation) and therefore may also work with hdparm.  E.g. recent WD "Passport" models and recent NexStar-3 enclosures.  Some options may work correctly only with the latest kernels.


Но ей пользуются в статье.

Справедливое замечание.
Моя задача была продемонстрировать особенности. Я же, для коллеги, рекомендовал бы использовать непосредственную запись на диск, а не в файл. Либо эту утилиту, если она имеется.

dd еще интересен тем, что использует вполен стандартный набор системных вызовов, т.е. результат не какой-то там рафинированный в IOT-ах, а максимально приближенный к тому, как будут работать остальные приложения.

Ну в первом приближении для объяснения, как померять скорость дисков может и поможет. Но как всегда в реальности все будет сложнее.

Почему команда sync используется отдельно, а не опцией в команде dd? А вдруг пользователь в фоне торренты качает, и отдельный sync уже показывает погоду на Марсе.

Командой hdparm выключают кэш самого носителя, выключается ли после этого файловый кэш в ОС - большой вопрос. И опять снова искажаются результаты тестирования.

Про кеши есть широкоизвестная в узких кругах статья, из которой на деле выясняются еще более пугающие подробности работы носителей.

https://yourcmc.ru/wiki/Производительность_Ceph#.D0.9A.D0.B0.D1.80.D1.82.D0.B8.D0.BD.D0.B0_.D0.BC.D0.B0.D1.81.D0.BB.D0.BE.D0.BC_.C2.AB.D0.A2.D0.BE.D1.80.D0.BC.D0.BE.D0.B7.D1.8F.D1.89.D0.B8.D0.B9_.D0.BA.D1.8D.D1.88.C2.BB

Тот редкий случай когда комментарии намного интереснее статьи!

Отличная статья. У меня сейчас как раз курсач по этой теме)

Берите скрипт и вставляйте красивые графики в курсач :)

Используйте общеизвестные утилиты как fio. Про использование утилиты dd можно написать только в первой главе как введение, не более. Потому, что на результаты тестирования еще влияют глубина очередей и их количество, использования fsync, fdatasync и тд, которые можно указывать в fio.

А еще влияет характер реальной нагрузки, скорость при которой внезапно упадет в несколько раз.

Надеюсь кто-нибудь запилит статью в духе "меряем скорость диска с помощью голанг как завещали деды". Где чувак тупо создаст файл на 10 гигов, потом скакнет в начало, стартанет таймер и запишет в файл какого-нить мусора из озу 1Гб блоком 10 раз, а потом остановит таймер. Такое будет работать не только на любом линуксе с голангом, но и даже более того, на винде. А кому не нравится голанг можно на чистом си запилить, чтобы уж совсем сурово. А можно еще более сурово, сделать сразу цикл 10 раз по 10 раз. Ударить статистикой, так сказать, по бездорожью! Во времена зеленой травы и красивых девушек через одну я примерно таким страдал, чтобы файлы по сетке коаксиальной гонять, ибо штатными средствами фильм по сети было не скопировать из-за постоянных коллизий, а "сосалка" очень бодренько по 1мб пачечками перекладывала, пачка 1кб - слишком тупила из-за накладных, пачка 10мб тупила потому что шанс поймать коллизию был уже велик, а вот 1мб вполне компромиссно. Помянем си-билдер и те лихие теплые лаповые времена! Кстати, в "сосалке" было на редкость мало непосредственно кода, строк 80 наверное, несмотря на гуй!

Зарегистрируйтесь на Хабре , чтобы оставить комментарий