26.04.2022

Копирование файлов

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

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

Речь тут идет об использовании каких-либо приложений, поддерживающих постановку задач копирования файлов в очередь. Я пользуюсь Total Commander.

Возможность подобной оптимизации конечно зависит от аппаратной части компьютера: позволяет ли подсистема ввода-вывода параллельные операции на физически разные накопители.

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

Лирическое отступление про кэш. В идеальной системе, где все приложения написаны максимально эффективно, видимо, нет особого места для файлового кэша на уровне операционной системы. Ну, по крайне мере я не вижу такого варианта использования, когда бы он пригодился.
Точнее, придумал тут один: когда вы открыли большой вордовский файл, закрыли его, и тут же вспомнили, что чего-то в нем не доделали. Вот тут кэш пригодится, да.

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

Издержки же на файловый кэш не очень значительны. Во-первых, это память. Но при нынешних ценах на ОЗУ в компьютерах её обычно с избытком, так что это не проблема.
Во-вторых, двойные пересылки память-память. Первый раз при чтении с устройства в буфер системы кэширования, затем второй раз при копировании из кэша в буфер приложения.
При записи те же два этапа сохраняются, только идут в обратной последовательности.
Так как современное ОЗУ весьма производительно, то пересылки память-память не сильно снижают производительность.

Все это была преамбула. Теперь же перейду к амбуле. Решил я посмотреть и проверить, а нельзя ли ускорить процесс копирования файлов?

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

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

В общем, слегка помаявшись с отладкой многопоточного приложения, в конце концов оттестировал его.

Как ни обидно, особого выигрыша по сравнению с несколькими копиями copy/xcopy достичь не удалось. 😂 Как, впрочем и проигрыша. У xcopy, кстати, тоже есть опция копирования без кэширования, как раз для больших файлов.
Есть подозрение, что причиной всему небольшие задержки в переключении потоков между "читателям" и "писателями".

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

20.04.2022

Ryzen 7 5800X

Походу, это последний американский процессор 😟, что мне удалось оттестировать. В системе 32 ГиБ ОЗУ DDR4 3200 МГц.

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

 

Можно сказать, что в области плавающей точки увеличение производительности весьма значительно, как за счет экстенсивных мер (увеличение количества ядер, кэша и исполнительных устройств), так и интенсивных (увеличение производительности  исполнительных устройств и шин передачи данных).

Средняя производительность за 7 лет увеличилась в четыре с лишним раза (от архитектуры PileDriver в 2013 году до Zen3 в 2020).
Однопоточная производительность выросла более чем в два раза на скалярных операциях и в 3.5 раза на векторных. Очень неплохо!

 

Немного скромнее обстоит дело с целочисленными скалярными операциями. Среднее ускорение всего лишь в 3.4 раза.

Однопоточное – "всего лишь" в 1.72 раза. При этом ускорение операции деления более значительно – в 1.81 раза, а вот более простые операции типа сложения и побитовых, ускоряются гораздо хуже в 1.66 раза. Видимо, эти операции и ранее были оптимизированы неплохо.


Видно, что и многопоточность реализована в новом процессоре более эффективно. Правда, есть странный провал на решении систем из 12 уравнений на типе double, где Ryzen 7 поколения Zen3 сливает Ryzen 5 поколения Zen2. Честно говоря, не знаю даже, как его можно объяснить