LINUX.ORG.RU

Все таки fread или mmap?

 , fread, ,


0

2

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

В продолжении темы

Имеется армка 512МБ рам и 512ГБ сд карта.

Суть - для построения журнала видео архива на носителе без файловой системы при прямом проходе (при обратном смещение 1 минута и перечитывается флешка за секунды) флешки выполняю смещение на размер кадра, для поиска нужным мне меток. Все в целом устраивало при перечитывании временных меток пока писал JPEG, который был размером где то 220КБ, но как только начал писать H264 перечитать флешку «вперед» стало проблемой иба кадры в основном около 15КБ.

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

Собсна глобальный вопрос - как бы ускорить чтение с носителя???

Второстепенный - fread vs fseeko какими буферами оперируют если читается фридом условно 20 байт и как его менять? setvbuf почему то чем то вроде setvbuf(pf, NULL, _IOFBF, 32 * 1024 * 1024) никак не влияет на скорость перечитывания носителя

Или может я просто уперся в физическую скорость флешки!?

★★★

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

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

anonymous
()

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

К чему это - к тупым рассуждениям про коунаду.

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

В сначала strace'ом посмотрите, во что превращаются ваши fread(). В read() с каким размером буфера? Естестено, на тестовом примере. А потом посмотрите какую скорость показывает dd на чтение флешки и насколько скорость меняется при изменении размера блока (буфера чтения).

Не следил, не знаю, почему вы не стали переходить на read(), но, если сложно, не удобно переделывать код с fread(20 байт) на read() большим блоком и работу с этим блоком, то и на mmap() переход будет не легче.

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

Спасибо, буду разбираться

У меня основная задача это fwrite, буфер которой уже выровнен по размеру сектора, изредка когда надо качнуть архив сразу делаю fread по 2МБ, что даёт где то до 60мбит/с трафика с железки, так что единственная проблема при загрузке как то быстрей перечитать флешку, когда запись ее остановилась близко к концу.

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

посмотрел strace таким образом

strace -f -e trace=read -o trace.dump ....

получились дефолтные вызовы

10363 read(6, "..."..., 4096) = 4096
10363 read(6, "..."..., 4096) = 4096

при этом setvbuf никак не влияет на fread

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

mmap используют не для скорости, его используют для упрощения кодинга (в коде не надо вставлять явный вызов read). С помощью read ты можешь вручную организовать всё чтение как надо и быстрее. Но судя по твоим дурацким вопросам, сделать ты это не осилишь.

И не используй fread, используй read.

firkax ★★★★★
()

Напиши синтетический бенчмарк, где сравни fread и mmap в интересующей тебя задаче. За тебя это делать никто не будет.

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

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

вот без оценки конешно ну никак

почему не использовать fread? потому что это «по дурацки»? «как надо и быстрее это» как?

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

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

его используют для упрощения кодинга

вы б хоть хабр открыли, там написано что с mmap кодинг УСЛОЖНЯЕТСЯ

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

fread это обёртка над read, только с кучей лишнего ненужного.

Скорость растёт потому что это нубы, которые сначала абы как вызывают read а потом абы как вызывают mmap, и при этом у них много памяти, что позволяет засунуть файл целиком в память, ну или значительную его часть.

Читать с помощью read по 1 байту и правда выйдет очень медленно, но так делать не надо - изучи как всё работает и сделай нормальный интерфейс к файлам на диске. За тебя, именно для твоей проги, никто это делать не будет. mmap, повторю, хорош лишь тем, что с ним кодингом своего индивидуально оптимизированного алгоритма работы с диском можно не заниматься, и результат будет более-менее вменяемый. Но если хочешь сделать наилучший вариант - надо его делать вручную.

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

большим блоком

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

Причем при обратном поиске читать по 512Б тк там только метка на следующую минуту, а при прямом видимо несколько МБ придется, тк смещение только на размер кадра следующее

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

С другой стороны если fread читает блоками по 4к, как ему задать, чтоб он при чтении 20 байт прочитал сразу условно 20 мб и при fseeko не выполнял следующее чтение если это внутри буфера )

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

Это разовая операция при загрузке, есть желание сделать её быстрее

при загрузке перечитать ВСЮ флешку, это хреновая затея..кадр (с ваших слов) в среднем 15Kb, страница 4 Кб. Читать по 20 байт через каждые 2-3 страницы, почти всё равно что прочесть всю флешку.

Не пишется в отдельное место, чтобы место не перетерлось до дыр )

пишите в 2 места :-) как старый добрый FAT

или

сколько у вас кадров максимум влезает ? 100k ?? так и разделите - метаданные пост-фактум пишутся в один (или даже 2) блок на 100тыщ фиксированных записей, видеоданные в оставшуюся часть зато записи там переменной длины. И вот блок с метаданными - кандидат для mmap, он просто готовый массив.

PS. хотите сэкономить на циклах перезаписи флешек ? уже пару лет разрабатываете, за те-же деньги можно было оптом купить ЗУ понадёжнее, внедрить и даже продавать проектом... вы пока закончите, флешки выйдут из моды и станут дикой редкостью..

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

Проект закончен и уж 2 года работает, оптимизация сэр под новые задачи )

Нет конечно не по 20 байт всю флешку, просто в них содержится смещение на следующий кадр и для х264 это будет условно смещение по 15кб 29 раз и 150кб на 30ый.

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

хотите сэкономить на циклах перезаписи флешек ?

Именно, не менее 7 лет хочу выжать из самых дешевых флешек, а перечитывание происходит в общем случае раз в неделю из за ребута чужого ПО, которое крутится параллельно на железке, я б вообще никогда не ребутился годами

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

хочу 7 лет выжать из флешек

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

Да и проверить результат затруднительно. Тестовый прогон в 2 года ? дайте два

вот как-то диагностировать сбои, начинающиеся тормоза и вовремя верещать «меняй флешку сцуко» - видится более практичной вещью

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

сколько у вас кадров максимум влезает ? 100k ?

Не считал, придут другие камеры где gop 2 секунды и опять мудрить с аналогом таблицы содержания, практика пока показывает что хранить ее в памяти эффективнее.

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

Насколько я знаю, стандарты нигде не требуют, чтобы fread() превращался в read() с размером буфера, указаным через setvbuf(). То есть, что захотели в конкретной реализации libc, то и написали. Поэтому в куче программ fread() и не используют, самостоятельно реализуют его функционал, делают read() в большой буфер и разгребают его содержимое.

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

А как физическая безопасность обеспечивается? Ну чтобы если вдруг кто-то решил унести камеру, то и записанной с ней не пропадало? А кто флэшки в камерах менять будет?

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

Пока менялись только «камеры», с переставлением флешки )

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

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

Да вот и есть сомнения, тк мне не нужны все 512гб при чтении в журнал, а только около 20 байт приблизительно через 15кб

От fread буду отказываться, чтобы попытаться прочитать не 4кб за раз, а наверное 16мб и уже их парсить, при выгрузке архива уже выкинул, тк глупо конечно читать в буфер по 4кб, когда буфер 2мб

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

около 20 байт приблизительно через 15кб

Тогда очевидно эти 20 байт надо класть отдельно (например в отдельный файл, память и т.д.). Это называется индекс, стандартный паттерн для всех БД:-)

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

AntonI ★★★★★
()

В продолжении темы

Не читал но осуждаю тебе разве не объяснили что fread в итоге это всё равно mmap?

setvbuf почему то чем то вроде setvbuf(pf, NULL, _IOFBF, 32 * 1024 * 1024) никак не влияет на скорость перечитывания носителя

Потому и не влияет. В итоге ядро всё равно делает mmap. Не страдай хернёй, ничего никак не ускорить.

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

Читать с помощью read по 1 байту и правда выйдет очень медленно

Медленно оно выйдет не потому что 1 байт, а потому что дохрилион переключений контекста. Читается/mmapится оно всё равно сразу блоком.

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

надо проверить, 12мб/c скорость чтения через dd

dd if=/dev/mmcblk1 of=/dev/null status=progress bs=xM

может по 512б будет быстрее и смещение на 15кб, чем 4к чтение и тоже самое смещение или чтение целиком скажем 16Мб и его парсинг

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

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

может по 512б будет быстрее и смещение на 15кб, чем 4к чтение и тоже самое смещение

Если читать через fread/mmap то должно быть одинаково

чтение целиком скажем 16Мб и его парсинг

Это должно быть чуток быстрее, но зависит от настройки readahead.

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

А зачем вы обновляете по 20 байт? Идёт поток кадров, доя каждого кадра сохраняете его 20 байт в память отдельно, как блок набрался - пишете на флешку.

Скорее всего ос так и делает если флэш лишний раз не дёргать. Не надо пытаться быть умнее ос:-)

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

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

потому что обновляя 20 байт, вы обновляете на флешке целиком весь сектор 512Б (4к) и таким образом это место очень быстро станет «дыркой»

пиши частичные индексы. Образно - каждые N кадров индекс ( сколько влезет в 4k). Получится 2 типа записей - индекс следующих N кадров и собственно кадры. Как skip-list

чтобы между индексными блоками была существенная дистанция, не как сейчас (2-3)*4K.

Сейчас когда чтение по 20 байт(1-го блока 4k) через 15Kb - тебе всё равно чем читать, mmap/read/fread - ты всё равно считываешь ВСЮ полностью флешку.

MKuznetsov ★★★★★
()

а вообще для флешек есть их специфические ФС. Которые учитывают циклы перезаписи и ещё 100500 особенностей.

бегло глянул за вас, навскидку видятся :

- http://www.linux-mtd.infradead.org/doc/ubifs.html

- https://f2fs.wiki.kernel.org/

НО, там-же чёрным по белому - «some modern devices already have FTL layer», то есть там УЖЕ внутри свой микро-контролллер который ремапит и заботится про перезапись блоков.

НЕ НАДО ПРО ЭТО ПЫХТЕТЬ

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

) так где потом этот блок то искать, в котором записались координаты меток, вот для обратного поиска так и сделано - каждую минуту пишется метка предыдущей минуты и обратный поиск по 512Гб флешки секунды занимает, потому что там никакое ни чтение большими блоками выполняется, а тупое смещение на херову тучу мегабайт за раз - прикидывал это дает для кадров мжпег по 220-240кб скорость порядка 300-400мб/c при обратном перечитывании флешки.

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

ЯННП - а зачем его где то искать?

  1. Вот есть поток кадров, для каждого кадра какая то метаинформация (20байт). Так?

  2. иногда надо посмотреть только метаинформацию кадров не трогая по возможности кадры. Так?

Тогда кладем метаинформацию отдельно. Работаем с ней так же как с кадрами - есть пачка кадров по сколько то там байт, отдельно есть пачка 20байтных записей.

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

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 2)