Мне нужно написать программу на C (или C++) в Linux
, которая будет тестировать скорость записи и чтения в разных файловых системах. Я должен быть уверен, что все данные записаны на диск (не в кеш).
Итак, мой первый вопрос - какую функцию я должен использовать для открытия нового файла? Раньше я использовал функцию open
с параметрами O_DIRECT
и O_SYNC
, и все было хорошо, кроме одного — запись небольших файлов, например, 1 КБ, была очень медленной, что-то вроде 0,01 МБ/с.
Я пытался использовать функцию fopen
вместо open
и функцию fflush
, чтобы быть уверенным, что все данные записываются непосредственно на диск, и сначала протестировал ее на файловой системе FAT32
. 1000 файлов размером 1 КБ было записано на диск (здесь SD-карта) за 5 секунд. что-то вроде 0,18 МБ/с, и я думаю, что это правильно.
Теперь проблема возникает при тестировании файловых систем EXT4
и NTFS
. EXT4
. Файлы размером 1 КБ были записаны со скоростью около 12 МБ/с (неправильно), при тестировании передача 100 КБ была 180 МБ/с (ужасно неправильно, моя SD-карта имеет скорость передачи всего 20 МБ/с).
Мой фактический код для записи файлов выглядит так:
clock_gettime(CLOCK_REALTIME, &ts);
for ( int i = 0; i < amount; ++i)
{
p = fopen(buffer2, "w+");
fwrite(buff, size*1024, 1, p);
if ( fflush(p) != 0 ) { cout << "fflush error"; return 0; }
fclose(p);
}
clock_gettime(CLOCK_REALTIME, &ts2);
time2 = diff2(ts,ts2);
хорошо работает только для файловой системы FAT32
. Второй код (использовавшийся ранее) выглядит так:
for ( int i = 0; i < amount; ++i)
{
int fd = open(buffer2, O_WRONLY | O_CREAT, 0777);
if ( error(fd, "open") ) return false;
if ( (write(fd, buff, size*1024)) < 0 ) { perror("write error"); return 0; }
if ( (fsync(fd)) == -1 ) { perror("fsync"); return 0; }
close(fd);
}
работает для всех файловых систем, но маленькие файлы записываются очень медленно. Может быть, мне следует использовать другой код для другой файловой системы? Любые идеи?
EDIT
:
Я обнаружил, почему запись небольших файлов выполняется медленно. Это из-за функции fsync
, и в разных файловых системах это занимает разное время. Я звоню fsync
при каждой записи, вот в чем проблема.
Есть ли способ вызвать его в конце, когда все файлы будут записаны? Или, может быть, каждые несколько секунд? Должен ли я использовать другую нить?
fsync
. Это гарантирует, что файл за файловым дескриптором правильно синхронизирован с диском. И O_DIRECT, и O_SYNC, вероятно, ухудшат общую производительность. - person Art   schedule 11.04.2013