Сейчас на форуме: UniSoft, laslo, bartolomeo (+5 невидимых)

 eXeL@B —› Программирование —› Быстрая запись со случайным доступом файлов > 4 Гб
Посл.ответ Сообщение


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 27 августа 2011 09:09 · Поправил: DenCoder
· Личное сообщение · #1

Возможно вообще такое?

NTFS. Нужно писать файл 16Гб. Первый вариант кода одну запись до 2 минут писал по определённому смещению (SetFilePointer). Сейчас использую
Code:
  1. FILE_FLAG_RANDOM_ACCESS
  2. FILE_FLAG_NO_BUFFERING
  3. FILE_FLAG_WRITE_THROUGH
кодес такой
Code:
  1. void CTwinsA5Dlg::WriteToBase(DWORD dwHash, DWORD dwFirst)
  2. {
  3.          LONG uDistanceHigh = dwHash / 0x40000000;
  4.          LONG uDistanceLow = dwHash * 4;
  5.          DWORD dwBytesRead, dwBytesWritten, dwSectorAlign = uDistanceLow & (-1 ^ (BytesPerSector - 1));;
  6.          SetFilePointer(hBigFile, dwSectorAlign, &uDistanceHigh, FILE_BEGIN);
  7.          ReadFile(hBigFile, rwBuffer, BytesPerSector, &dwBytesRead, NULL);
  8.          *(DWORD*)(rwBuffer + (uDistanceLow % BytesPerSector)) = dwFirst;
  9.          SetFilePointer(hBigFile, dwSectorAlign, &uDistanceHigh, FILE_BEGIN);
  10.          WriteFile(hBigFile, rwBuffer, BytesPerSector, &dwBytesWritten, NULL);
  11. }

rwBuffer выделен VirtualAlloc...
и не пойму, ускорилось или нет... - всё равно медленно. Кто-нибудь решал уже такую проблему? Придётся бить файл на 4 части или можно без этого?

UPD. Пошло быстрее, конечно - только поначалу при значительных изменениях смещений тормоза были... но всё равно медленно...

-----
IZ.RU





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 27 августа 2011 09:54
· Личное сообщение · #2

Попробуй флаг FILE_FLAG_SEQUENTIAL_SCAN, мне при работе с флешкой в RAW режиме помогло.

-----
Yann Tiersen best and do not fuck





Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 27 августа 2011 15:30
· Личное сообщение · #3

DenCoder
чисто теоретически в 4гб куски должно пошустрее писать, если x32. проэкспериментить с замером времени, имхо, лучше на флехе.

-----
От многой мудрости много скорби, и умножающий знание умножает печаль




Ранг: 1.3 (гость), 1thx
Активность: 0=0
Статус: Участник

Создано: 28 августа 2011 01:55
· Личное сообщение · #4

Тормозит в случае записи по большим смещениям из-за необходимости предварительной записи нулей. Например если нам надо записать 4 байта по смещению 0x300000000 и у нас пустой файл нулевого размера, то сначала на диск запишется 12 Гб нулей и только потом наши 4 байта.

Варианты оптимизации в зависимости от планируемого наполнения этого файла:

1) Если весь 16 Гб файл будет заполняться данными, то самое разумное сначала создать пустой файл на 16 Гб (забитый нулями), разумеется это займёт некоторое время. Зато потом запись в конкретное место уже не будет так тормозить, ибо будут записываться только конкретные данные, нули уже писаться не будут.

2) Если же бОльшая часть этого 16Гб файла будет пустовать, то как вариант экономии времени и пространства на диске - использование разреженных файлов NTFS --> Link <--. В таком случае нули на диск писаться не будут и файл будет занимать на диске места примерно столько, сколько в нём есть именно ненулевых данных, нули же будут при чтении "подставляться" драйвером, без обращений к диску.

| Сообщение посчитали полезным: DenCoder


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 28 августа 2011 03:21 · Поправил: DenCoder
· Личное сообщение · #5

roman_pro пишет:
Например если нам надо записать 4 байта по смещению 0x300000000 и у нас пустой файл нулевого размера, то сначала на диск запишется 12 Гб нулей и только потом наши 4 байта.

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

roman_pro пишет:
использование разреженных файлов NTFS

Спасибо! - почитаем ) Может быть, поможет... Сейчас оптимизирую накоплением данных с задержкой записи. По накоплению предельного числа данных буфер за буфером по выровненным смещениям сначала считыается, добавляется информация и записывается. Кажется, это единственный вариант, поскольку, похоже, что винде всё равно - 4 байта это или сектор.

UPD. Более подробно о спарс-файлах в --> книге Руссиновича, часть 4 <--. Также о них упоминается и в 3 части... Оцените силу WinDbg

PE_Kill пишет:
FILE_FLAG_SEQUENTIAL_SCAN

Я тут подумал, этот флаг бесполезен, как и FILE_FLAG_RANDOM_ACCESS, ведь запись в обход кеша. А в обход потому, что кеш у винды маловат и из-за случайного доступа винде приходится часто его сбрасывать, в то время как полезных данных там низкий процент. Что и занимает время. Если б был последовательный доступ, от сектора к сектору, тогда да - FILE_FLAG_SEQUENTIAL_SCAN мог бы помочь.

UPD2. Что интересно, Break/Step out подгоняет процесс записи. Интересно, почему?
UPD3. В данном конкретном случае спарс-файлы всё же не подходят... Ну увеличится не много скорость на старте... и то, если писать секторами. Однако, как оказалось, (произвольный доступ превратили в последовательный с коэффициентом полезной нагрузки аж 0.1% - будем увеличивать) лучше писать буферами по 1-2 МБ, тогда скорость для моего харда будет в 100 МБ/сек. Попробуем достигнуть хотя б 1% пользы. Это не так просто, поскольку объём требуемой памяти растёт, а с ним и кол-во обращений к файлу подкачки. Хотя и на разных дисках файл подкачки и диск, на который пишу, похоже у контроллера предельная общая пропускная способность...

-----
IZ.RU



 eXeL@B —› Программирование —› Быстрая запись со случайным доступом файлов > 4 Гб
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати