Почему запись в существующий файл быстрее, чем создание нового файла?

Вопрос или проблема

Я заметил странные ограничения в Windows относительно производительности записи файлов на SSD: а именно, я, похоже, не могу записывать в один файл со скоростью более 3-4 ГБ/с. Записывая несколько файлов одновременно, я могу заполнить пустой диск на 4 ТБ со скоростью 6 ГБ/с, но не в один файл, и, к сожалению, именно это мне и нужно сделать.

В помощь приходит fio, который позволяет мне записать 6 ГБ/с в один файл при условии, что этот файл предварительно выделен. В противном случае я могу записывать только с упомянутыми ранее 3-4 ГБ/с.

Вот fio.txt:

[global]
thread
bs=1M
rw=write
iodepth=8
direct=1

[job1]
filename=fio.bin
size=100G

А затем я выполняю

fio fio.txt

дважды, в результате чего получается следующий вывод:

E:\>fio fio.txt
job1: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=windowsaio, iodepth=8
fio-3.38
Начинается 1 поток
job1: Распределение IO файла (1 файл / 102400MiB)
Задачи: 1 (f=1): [W(1)][100.0%][w=4271MiB/s][w=4271 IOPS][eta 00m:00s]
job1: (groupid=0, jobs=1): err= 0: pid=5732: Ср 23 окт 01:48:16 2024
  запись: IOPS=4253, BW=4254MiB/s (4460MB/s)(100GiB/24073мсек); 0 сбросов зоны
    slat (usec): min=200, max=1630, avg=234.47, stdev=25.03
    clat (nsec): min=490, max=3012.7k, avg=941622.54, stdev=473495.82
     lat (usec): min=231, max=3339, avg=1176.10, stdev=472.11
    clat перцентиль (usec):
     |  1.00th=[  217],  5.00th=[  227], 10.00th=[  241], 20.00th=[  461],
     | 30.00th=[  676], 40.00th=[  717], 50.00th=[  930], 60.00th=[ 1156],
     | 70.00th=[ 1221], 80.00th=[ 1401], 90.00th=[ 1614], 95.00th=[ 1647],
     | 99.00th=[ 1762], 99.50th=[ 1795], 99.90th=[ 1860], 99.95th=[ 1942],
     | 99.99th=[ 2089]
   bw (  MiB/s): min= 4041, max= 4294, per=100.00%, avg=4254.81, stdev=36.63, samples=48
   iops        : min= 4041, max= 4294, avg=4254.54, stdev=36.74, samples=48
  lat (nsec)   : 500=0.01%, 750=0.01%
  lat (usec)   : 2=0.21%, 4=0.01%, 20=0.01%, 250=11.45%, 500=15.97%
  lat (usec)   : 750=14.30%, 1000=14.11%
  lat (msec)   : 2=43.94%, 4=0.02%
  cpu          : usr=12.46%, sys=12.46%, ctx=0, majf=0, minf=0
  IO depths    : 1=0.2%, 2=28.5%, 4=57.0%, 8=14.3%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=87.5%, 8=12.5%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,102400,0,0 short=0,0,0,0 dropped=0,0,0,0
     задержка   : target=0, window=0, percentile=100.00%, depth=8

Статус выполнения группа 0 (все задачи):
  WRITE: bw=4254MiB/s (4460MB/s), 4096MiB/s-4254MiB/s (4295MB/s-4460MB/s), io=100GiB (107GB), run=24073-24073msec
E:\>fio fio.txt
job1: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=windowsaio, iodepth=8
fio-3.38
Начинается 1 поток
Задачи: 1 (f=0): [f(1)][100.0%][w=6007MiB/s][w=6007 IOPS][eta 00m:00s]
job1: (groupid=0, jobs=1): err= 0: pid=4788: Ср 23 окт 01:48:36 2024
  запись: IOPS=6065, BW=6066MiB/s (6361MB/s)(100GiB/16881мсек); 0 сбросов зоны
    slat (usec): min=27, max=421, avg=38.99, stdev= 6.16
    clat (usec): min=356, max=2708, avg=1279.41, stdev=78.91
     lat (usec): min=436, max=2744, avg=1318.40, stdev=78.68
    clat перцентиль (usec):
     |  1.00th=[ 1156],  5.00th=[ 1172], 10.00th=[ 1172], 20.00th=[ 1205],
     | 30.00th=[ 1237], 40.00th=[ 1270], 50.00th=[ 1287], 60.00th=[ 1303],
     | 70.00th=[ 1319], 80.00th=[ 1336], 90.00th=[ 1352], 95.00th=[ 1385],
     | 99.00th=[ 1418], 99.50th=[ 1450], 99.90th=[ 2057], 99.95th=[ 2278],
     | 99.99th=[ 2540]
   bw (  MiB/s): min= 3783, max= 6220, per=99.03%, avg=6006.92, stdev=413.39, samples=34
   iops        : min= 3783, max= 6220, avg=6006.65, stdev=413.46, samples=34
  lat (usec)   : 500=0.01%, 750=0.01%, 1000=0.03%
  lat (msec)   : 2=99.84%, 4=0.12%
  cpu          : usr=11.85%, sys=5.92%, ctx=0, majf=0, minf=0
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=99.9%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,102400,0,0 short=0,0,0,0 dropped=0,0,0,0
     задержка   : target=0, window=0, percentile=100.00%, depth=8

Статус выполнения группа 0 (все задачи):
  WRITE: bw=6066MiB/s (6361MB/s), 4096MiB/s-6066MiB/s (4295MB/s-6361MB/s), io=100GiB (107GB), run=16881-16881msec

Почему запись в существующий файл может иметь значение по сравнению с записью в новый файл? И, что наиболее важно, есть ли способ для меня достичь высокой скорости записи, не выделяя файл заранее, например, подготовив файловую систему определённым образом?

(Я видел связанные вопросы, но они касались меньших файлов, Linux (где я могу записывать 6 ГБ/с в тот же файл), Java или вообще находил противоположный эффект.)

.

Ответ или решение

Когда речь заходит о скорости записи данных на жесткие диски или твердотельные накопители (SSD), важно понимать, что процессы записи в существующий файл и создание нового файла могут существенно различаться по производительности. Рассмотрим, почему запись в существующий файл может быть быстрее, и как можно оптимизировать процесс записи без предварительного выделения файла.

Почему запись в существующий файл быстрее?

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

  2. Скорость записи на SSD: Твердотельные накопители (SSD) используют внутренние механизмы распределения данных, которые оптимизированы для последовательной записи. Если данные записываются в существующий файл, система использует эти оптимизированные пути маршрутизации на уровне контроллера SSD, что значительно ускоряет процесс по сравнению с записью новых данных, которые требуют дальнейшего разделения и размещения.

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

  4. Параллелизм и управление потоками: Современные операционные системы и SSD часто поддерживают параллельные процессы записи. Если файл уже открыт и доступен для записи, система может оптимизировать свой подход к записи, используя несколько потоков на уровне ввода-вывода, что также увеличивает производительность.

Как достичь высокой скорости записи без предварительного выделения файла?

  1. Оптимизация файловой системы: Некоторые файловые системы, такие как NTFS на Windows или Ext4 на Linux, могут вести себя по-разному в зависимости от настроек. Рассмотрите возможность использования специализированных вариантов настройки, таких как уменьшение размера кэша или использование возможностей SSD.

  2. Использование режима прямого доступа: Как показано в вашем тесте с использованием fio, параметр direct=1 активирует режим прямого доступа, который обходит кэш системы. Это может помочь улучшить скорость записи в определенных ситуациях.

  3. Регулярная дефрагментация: Если вы работаете с HDD (жесткий диск), регулярная дефрагментация может значительно улучшить скорость записи, создавая непрерывные блоки свободного пространства, что упрощает процесс записи новых данных.

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

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

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

Оцените материал
Добавить комментарий

Капча загружается...