LINUX.ORG.RU

fread/fwrite

 ,


0

2

Приветствую!

Продолжаю мучать тему С++ vs прямая запись на флешку

Как я понял эти методы буферные и фактическая запись осуществляется либо по fflush, либо где то задан системный размер кеша? как его менять? а «померить» можно текущий размер буфера? например, делать ффлуш через заданный размер, а не количество циклов записи или держать кеш выравненной длины относительно размера сектора

актуально для ubuntu/debian

★★★

Последнее исправление: wolverin (всего исправлений: 1)

Ответ на: комментарий от wolverin

хотя это буфер библиотеки, а мне видимо нужен буфер ОС

wolverin ★★★
() автор топика

фактическая запись осуществляется либо по fflush

Нет, по fflush фактическая запись не осуществляется.

Note  that fflush() flushes only the user-space buffers provided by the C library.  To ensure that the data is physically stored
on disk the kernel buffers must be flushed too, for example, with sync(2) or fsync(2)
gremlin_the_red ★★★★★
()

Всё-таки ещё раз порекомендую навернуть Linux System Programming, Robert Love, 2013, главу вторую, там есть раздел Synchronized I/O.

agentgoblin
()
Ответ на: комментарий от gremlin_the_red

gremlin_the_red

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

или вообще лучше не мешать операционке работать!? просто кеш почти 200Мб, при памяти всего в 512

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от agentgoblin

Роберт Любовь конеш четкий писатель, но если Вам не сложно можете подсказать, что конкретно нужно сделать, чтобы делаю я кучу врайтов, а на диск пишется четко кеш выравненный по размеру сектора? да чтоб этот кеш еще не занимал 30% оперативки

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от wolverin

спасибо, а как кеш операционке задать?

Никак. Кэш записи можно ограничить параметрами vm.dirty_bytes/vm.dirty_ratio

или вообще лучше не мешать операционке работать!?

Да.

просто кеш почти 200Мб, при памяти всего в 512

Free mem — wasted mem ©

gremlin_the_red ★★★★★
()
Ответ на: комментарий от wolverin

Непонятно почему тебя вообще это беспокоит. Ну да запись отложенная, но так или иначе данные будут записаны. Тебе не нужно по этому поводу ничего специально делать.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

потому что памяти мало, 30% занято кешем это архи много + может питания пропадать на железке, которая пишет видео

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

конкретно нужно сделать, чтобы делаю я кучу врайтов, а на диск пишется четко кеш выравненный по размеру сектора

Ничего не нужно делать, это всегда так.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

dd не создает такой хрени, так что не всегда

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от no-such-file

размер блока данных (jpeg кадра) от 50кб до 200 кб, при этом кеш от 5% до 30%, в коде не меняется ничего при этом.

ну не выделяю я нигде 200Мб памяти… рост в 1000 раз происходит, только когда писать начинаю 15 раз в секунду по 50 или 200 кб

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

потому что памяти мало, 30% занято кешем это архи много + может питания пропадать на железке, которая пишет видео

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

уменьшением такого кеша иы лучше не сделаешь. просто будет бестолку у тебя находиться в системе пустое озу.

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

в нормальных ос и фс размеры физ буферов из которых делается сброс на блочный физ носитель или чтение с него, всегда кратны размеру блока носителя, а обычно просто ему равны.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

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

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

wolverin ★★★
() автор топика
Ответ на: комментарий от alysnix

про не нужное уточню, размер показывает top используемой памяти моим бинарником, который конечно же меньше 30% (но больше 5%), поэтому и не понимаю откуда такие цифры

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

в нормальной ФС физический сброс должен происходить по трем событиям

  • прямая инициация сброса
  • таймер
  • превышение размера накопленных данных

плюс данные будут лежать в неиспользуемой памяти(на случай чтения), пока эту память не заберут под другие нужды… типа загрузить еще прогу например.

alysnix ★★★
()
Ответ на: комментарий от alysnix

превышение размера накопленных данных

этот размер задается на уровне ФС или операционки? т.е. речь про использование vm.dirty_bytes/vm.dirty_ratio или в самой ФС какой то волшебный размер задан, связанный с размером логического сектора? (256 кб в среднем по палате?)

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)

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

актуально

Ну так прочитай уже как что делается в секциях man 2 и 3 или в книжке про программирование под юниксы/линуксы, где просто и понятно про писанину на диск (если не понятно и не просто — возьми другую книжку), чем плодить темы про пережеванные 100500 раз вопросы. Вариант ответа на твои вопросы «никак» тоже правильный. Обычно говорит о том что ты хочешь странного.

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

прочитать все подряд конечно хорошо, но мне бы что то покороче, как и размер буфера, который кроме размера меня всем устраивает )

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

Ну ограничься темой «файловый ввод/вывод» в хорошей книжке где тебе будет все понятно :)

slackwarrior ★★★★★
()

man 2 open? O_SYNC и write() по 512 байт за раз.

xaizek ★★★★★
()

Есть stdio буфер в адресном пространстве процесса, и есть блочный кеш в ядре. Можно отключить блочный кеш для файла, открыв его с флагом O_DIRECT. Только буфер в юзерспейсе должен быть тогда выровнен по границе страницы и размером в целое количество страниц:

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(void)
{
    int fd = open("file", O_RDWR | O_DIRECT | O_CLOEXEC);
    FILE *f = fdopen(fd, "w+e");
    size_t size = 4 * 1024;
    void *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    int i;
    setvbuf(f, (char *)buf, _IOFBF, size);
    for (i = 0; i != size; ++i)
        fprintf(f, "hello, world!\n");
    fclose(f);
    return 0;
}

strace:

openat(AT_FDCWD, "file", O_RDWR|O_DIRECT|O_CLOEXEC) = 3
fcntl(3, F_GETFL)                       = 0xc002 (flags O_RDWR|O_DIRECT|O_LARGEFILE)
brk(NULL)                               = 0x8f1000
brk(0x912000)                           = 0x912000
brk(NULL)                               = 0x912000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f389f632000
write(3, "hello, world!\nhello, world!\nhell"..., 4096) = 4096
write(3, "orld!\nhello, world!\nhello, world"..., 4096) = 4096
write(3, "llo, world!\nhello, world!\nhello,"..., 4096) = 4096
write(3, "ld!\nhello, world!\nhello, world!\n"..., 4096) = 4096
write(3, "o, world!\nhello, world!\nhello, w"..., 4096) = 4096
write(3, "!\nhello, world!\nhello, world!\nhe"..., 4096) = 4096
write(3, " world!\nhello, world!\nhello, wor"..., 4096) = 4096
write(3, "hello, world!\nhello, world!\nhell"..., 4096) = 4096
write(3, "orld!\nhello, world!\nhello, world"..., 4096) = 4096
write(3, "llo, world!\nhello, world!\nhello,"..., 4096) = 4096
write(3, "ld!\nhello, world!\nhello, world!\n"..., 4096) = 4096
write(3, "o, world!\nhello, world!\nhello, w"..., 4096) = 4096
write(3, "!\nhello, world!\nhello, world!\nhe"..., 4096) = 4096
write(3, " world!\nhello, world!\nhello, wor"..., 4096) = 4096
close(3)                                = 0
exit_group(0)                           = ?
iliyap ★★★★★
()
  1. Если возможно не используй fread/fwrite/fflush — они для других задач
  2. Пиши весь кадр одним write/writev. Если прям сильно хочется кусками - не стоит резать мельче чем 128 килобайт.
  3. И как тебе уже обьяснили — твое узкое место — журнал. Держи хотябы три копии, и как только одна из копий наебнется — требуй смены SD-карты
cvv ★★★★★
()
Ответ на: комментарий от cvv

Я сделал буфер 256к у библиотеки стдио и рассчитываю, что он выталкивается этим размером в кеш на запись, журнала у меня нет, я просто пишу в комментариях заголовка кадров, прямой поиск покадрово в таких условиях даёт около 150-300 мб/с при построении журнала, обратный вообще за секунду тестовую 32 Гб флешку перечитывает исходя из пакета 15 кадров * 60 сек

Поэтому не понимаю чем фрид фрайт плохи

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)
Ответ на: комментарий от wolverin

журнала у меня нет

ну и отлично

рассчитываю, что он выталкивается этим размером в кеш на запись

тебе подсказывали выталкивать в кеш SD-карты

не понимаю чем фрид фрайт плохи

путаются под ногами

cvv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.