Тестирование скорости записи/чтения на NTFS, FAT, EXT4

Мне нужно написать программу на 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 при каждой записи, вот в чем проблема.

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


person Tom    schedule 11.04.2013    source источник
comment
Посмотрите на функцию fsync. Это гарантирует, что файл за файловым дескриптором правильно синхронизирован с диском. И O_DIRECT, и O_SYNC, вероятно, ухудшат общую производительность.   -  person Art    schedule 11.04.2013
comment
В зависимости от того, почему вам нужно это сделать, вам может быть лучше использовать существующий тест производительности. Взгляните на IOZone. Источник доступен, поэтому, если вы когда-нибудь захотите посмотреть, как кто-то другой подошел к конкретному тесту, у вас есть хорошо проверенный справочник.   -  person Captain Obvlious    schedule 11.04.2013
comment
Не изобретайте велосипед, пожалуйста.   -  person devnull    schedule 11.04.2013
comment
@CaptainObvlious Спасибо, я проверю.   -  person Tom    schedule 11.04.2013
comment
Или Bonnie++, что может быть проще, если вы создаете его для своей платформы.   -  person Joe    schedule 11.04.2013


Ответы (1)


См. Как обеспечить запись данных на диск перед закрытием fstream? но я не думаю, что вы можете гарантировать, что данные действительно находятся на диске, а не в кеше контроллера диска или даже во встроенном кеше диска

person Martin Beckett    schedule 11.04.2013