Я должен написать программу на C (или C ++) в Linux
это будет тестировать скорость записи и чтения в разных файловых системах. Я должен быть уверен, что все данные записаны на диск (не в кэш).
Итак, мой первый вопрос — какую функцию я должен использовать, чтобы открыть новый файл? Я использовал раньше open
функция с параметрами O_DIRECT
а также O_SYNC
и все было хорошо, кроме одного — запись небольших файлов, таких как 1 КБ, была очень медленной, что-то вроде 0,01 МБ / с.
Я пытался использовать fopen
вместо этого open
, а также fflush
чтобы убедиться, что все данные записываются прямо на диск, и я сначала проверил FAT32
файловая система. 1000 файлов с 1KB было записано на диск (здесь 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
каждый пишет, так что здесь проблема.
Есть ли способ позвонить в конце, когда все файлы записаны? Или, может быть, каждые несколько секунд? Должен ли я использовать другой поток?
Увидеть Как убедиться, что данные записаны на диск перед закрытием fstream? но я не думаю, что вы можете гарантировать, что данные на самом деле находятся на диске, а не в кеше в контроллере диска или даже во встроенном кеше диска
Других решений пока нет …