2009-11-04 2 views
9

Мне нужно записать данные на диск. У меня есть два варианта:Что происходит быстрее, записывая необработанные данные на диск или записывая в файл?

  1. написать необработанные сектора (_ запись (ручка, пиксельный буфер, размер);)
  2. записи в файл (FWRITE (пиксельный буфер, размер, количество, Pfile);)
.

Какой способ быстрее?

Я ожидал, что функция записи исходного сектора, _write, будет более эффективной. Однако мой результат теста не удался! fwrite работает быстрее. _write стоит больше времени.

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

#define SSD_SECTOR_SIZE 512 
int g_pSddDevHandle = _open("\\\\.\\G:",_O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    _write(g_pSddDevHandle,szMemZero,SSD_SECTOR_SIZE); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
FILE * file = fopen("f:\\test.tmp","a+"); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    fwrite(szMemZero,SSD_SECTOR_SIZE,1,file); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
+4

Написание исходных данных вообще не зашифровано - это просто смущает пользователя ... – bdonlan

+3

+1 для профилирования. (Хотя этот вопрос выше моей головы) – GManNickG

+0

В bdonlan: Я просто хочу, чтобы это выглядело как зашифрованное ... для пользователей –

ответ

6

В случае _write() значение SSD_SECTOR_SIZE имеет значение. В первом случае размер каждой записи на самом деле будет BUFSIZ. Чтобы получить лучшее сравнение, убедитесь, что базовые размеры буфера совпадают.

Однако это, вероятно, только часть разницы.

В случае с fwrite вы измеряете, как быстро вы можете получать данные в память. Вы не сбросили буфер stdio в операционную систему, и вы не попросили операционную систему сбросить свои буферы на физическое хранилище. Чтобы более точно сравнить, вы должны вызвать fflush() перед остановкой таймеров.

Если вы действительно хотите получить данные на диске, а не просто получать данные в буферы операционных систем, вы должны убедиться, что вы вызываете fsync()/FlushFileBuffers() перед остановкой таймера.

Другие очевидные различия:

  • Приводы отличаются. Я не знаю, как это иначе.

  • Семантика записи на устройство отличается от семантики записи в файловую систему; файловой системе разрешено задерживать записи для повышения производительности, пока явно не сообщается (например, со стандартным дескриптором, вызовом FlushFileBuffers()); запись непосредственно на устройство не обязательно оптимизируется таким образом. С другой стороны, файловая система должна делать дополнительный ввод/вывод для управления метаданными (выделения блока, запись каталога и т.д.)

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

+0

Результат, который должен быть fwrite в 10 раз быстрее, чем _write ... SSD_SECTOR_SIZE is 512 –

+0

Если вы вызываете fflush() после каждого вызова fwrite, производительность должна выходить примерно равный. Однако, как упоминалось в janm, здесь есть и другие переменные, такие как кеш OS. –

+1

Если вы действительно заботитесь о производительности, я бы попробовал более крупные записи, скажем, 1 МБ за раз. Или даже просто один вызов функции записи, а затем вызов функции флеша. Современные диски не записывают сектора, они пишут треки. Чтобы получить точное сравнение, вы должны очистить буферы. – janm

18

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

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

Смежные вопросы