LINUX.ORG.RU

Как опрашивать датчик очень быстро и успевать писать данные в файл ?

 , , ,


3

3

Прога на borland c++ опрашивает датчик каждые 3 мс, накапливает данные в большой буфер, буфер memory mapped на файл и когда наполняется, прога делает сброс на диск. Периодически сброс на диск происходит 100-300 мс, вместо приемлых 1-2 мс. Происходит из-за этого подвисание опроса и пропускаем данные с датчика в те 100-300 мс, потраченные на сброс. Как бы лучше реализовать это ? Сейчас сброс на диск и опрос идут в одном потоке, у потока приоритет наивысший. Получится ли решить проблему, если сброс на диск делать в низкоприоритетном потоке ? Важно, чтобы пока идет сброс длительный, поток опроса продолжал работу. И как можно исправить эту проблему видимо с хардом ?

Ответ на: комментарий от alysnix
  1. уточню причину молотилки
  2. без понятия, думаю 2 ядра как и у нас.
  3. хард, точно не ssd, какие-то конкретные его параметры интересны ? Именно у заказчика не знаю, в другом городе сидят.
  4. уточню, но помню, что большими порциями получают с датчика.
user2132
() автор топика
Ответ на: комментарий от alysnix

еще что-то крутится и время ест, это будет мешать вашему приложению и вашим тредам.

А там кстати dr web стоит по тз и его выпилить нельзя) Может он лезет прогу проверять иногда ?

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

скорость записи, сколько мегабайт в секунду

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

ось виндовс небось? борланд с++ разве есть на линух?

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

А там кстати dr web стоит по тз и его выпилить нельзя) Может он лезет прогу проверять иногда ?

а вот запросто! че нить сканирует там. вот когда сканирует, сбросу мешает.

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

Можно приоритетами зажать. На процессор и на ввод-вывод

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

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

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

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

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

Если можно одно ядро целиком выделить

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

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

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

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

Мне нужно, чтобы когда 2 поток будет скидывать данные на диск, его выполнение прерывалось 1-ым потоком для опроса датчика. Как это сделать ?

Процессор может быть почти не занят, если задействован DMA. См. https://ru.wikipedia.org/wiki/Прямой_доступ_к_памяти

Занят он будет только логикой на уровне драйвера ФС. Хотя если там какой-то антивирус, который может проверять все операции записи на диск, типа «а не вирус ли туда в файл записывается» и эти проверки тормозят запись на диск до уровня, когда данные копятся в буфере быстрее, чем успевают записываться - всё плохо.

С работающим антивирусом эта задача в общем случае вообще нерешаема

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

С работающим антивирусом эта задача в общем случае вообще нерешаема

А можно как-то доказать заказчику, что в моменты просадки данных антивирус проявлял активность, что вина не проги)

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

Процессор может быть почти не занят, если задействован DMA. См. https://ru.wikipedia.org/wiki/Прямой_доступ_к_памяти

и в каком месте его задачи можно привернуть dma???

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

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

А можно как-то доказать заказчику, что в моменты просадки данных антивирус проявлял активность, что вина не проги)

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

но делать два треда, как я сказал, это академически верно, и неизбежно, чтобы не попасть в ад и там жариться вечно.

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

но делать два треда, как я сказал, это академически верно, и неизбежно, чтобы не попасть в ад и там жариться вечно.

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

Касательно DMA - там есть ньюанс, что буфер, из которого мы записываем в файл, должен быть особым образом выравнен. Вот что нагуглил https://www.pinvoke.net/default.aspx/kernel32/WriteFile.html

The documentation states that if using unbuffered IO, the memory must be «storage aligned» (aligned to the sector size of the storage device). Either this is not enforced, or managed allocations (specifically byte arrays) are automatically storage aligned because there seems to be no problem using it. Note that storage aligned and page aligned are not the same, and managed allocations are not in general page aligned (required for WriteFileScatter).

In fact the buffer must be aligned to the granularity of the SCSI/IDE adapter's DMA alignment (PDEVICE_OBJECT->AlignmentRequirement). The MSDN documentation is written for the lamers and probably it seemed safe to restrict them using the sector size (which is >= 512 byte, while most modern SCSI cards use <=4 byte requirement).

И тогда по-идее должно DMA задействоваться. В системном программировании под винды я не эксперт, в Borland C++ я тоже не эксперт, и вообще это всё оффтоп. Советую топикстартеру с такими вопросами идти в другие места, например в RSDN

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

А можно как-то доказать заказчику, что в моменты просадки данных антивирус проявлял активность, что вина не проги)

Смотри какие есть под винду мониторы I/O активности и загруженности процессора конкретными процессами, и посмотри графики, происходит ли что при таких-то ситуациях (когда данные записываются с буфера на диск) антивирус нагружает процессор т.к. проверяет данные, которые на диск твоя утилита записывает

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

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

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

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

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

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

А там кстати dr web стоит по тз и его выпилить нельзя) Может он лезет прогу проверять иногда ?

лол, рояль в кустах

Harald ★★★★★
()

Сейчас сброс на диск и опрос идут в одном потоке

а какого результата ты ещё ожидал?

anonymous
()
Ответ на: комментарий от user2132

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

можно ещё писать в БД (которая может находиться на другом компе), вызывая инсерты асинхронно, при этом добавляя время записи

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

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

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

чтобы скинуть на диск. хехе.

ты тоже про субд ничего не слышал, да?

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

ты тоже про субд ничего не слышал, да?

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

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

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

а где написано, что она асинхронная? и как ждать ее завершения, если она асинхронная?

Вот тут написано: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefi...

Writes data to the specified file or input/output (I/O) device. It reports its completion status asynchronously, calling the specified completion routine when writing is completed or canceled and the calling thread is in an alertable wait state.

To write data to a file or device synchronously, use the WriteFile function.

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

Вот тут написано: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefi

так это другая функция - «WriteFileEx». а та, что вы дали была синхронная WriteFile. я потому и удивился, что у нее явно синхронный интерфейс, и нет ничего про завершение.

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

Нет, я как раз писал про WriteFileEx, перечитайте еще раз.

Про просто WriteFile - это где я писал про выравнивание для DMA и давал ссылку https://www.pinvoke.net/default.aspx/kernel32/WriteFile.html - для WriteFileEx должны быть те же самые условия выравнивания по-идее

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

borland c++

Это ж для мастдайки. И при чем здесь линукс?

Как бы лучше реализовать это ?

Двойной буферизацией.

anonymous
()

Похоже никогда не узнаем какой размер потока данных.

Но если взять чисто для примера, что за раз приходит 1кб, тогда в секунду - 300кб. И что же там за диск, что такие проблемы с записью 300кб/c?

Txe
()
Ответ на: комментарий от lovesan

А что с ним не так в 2020? Компилятор бесплатный сейчас для скачивания, на том старом компе замечательно пашет.

grem ★★★★★
()

Может забить на memory mapped и просто использовать 2 буфера и асинхронную запись в файл?

anonymous
()
Ответ на: комментарий от user2132

А можно как-то доказать заказчику, что в моменты просадки данных антивирус проявлял активность, что вина не проги)

Проблема в том, что если даже анализ производительности покажет, что антивирус не виноват в данном конкретном случае, это не гарантирует, что антивирус не создаст проблем в будущем. Если есть в тз требования к дедлайнам для тех или иных операций, и недопустимости потери данных в случае несоблюдения дедлайнов, то это задача жесткого реального времени, и решается она по-хорошему не на ширпотребных системах, пускалках видеоплеера и апачика с вебсайтиком (Windows и Linux). И никакие приседания в виде нескольких потоков, смены диска на более быстрый и проч. припарки вам не помогут, если система принципиально не подходит под задачу.

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

какие-то просаживания идут и сброс на 100 мс занимает

Контроллер диска долго ищет сектор. Сильно зависит от возраста диска, число переаллокаций секторов. Нужно писать минимизируя время перемещения головок. Обычно резервируют непрерывные raw партишн и пишут туда без участия драйвера фс. Винду или линукс выкинуть вообще даже для мягкого рилтайма ни категорически не годятся, QNX и ничего другого.

Uncle_Bobby
()
Ответ на: комментарий от romanlinux

Эмм, каким конкретно образом БД может сделать что-то быстрее по сравнению с прямой записью в файл?

Вот если RAID0 массив сделать - это может что-то исправить, если узкое место там - запись на диск

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

Обычно резервируют непрерывные raw партишн и пишут туда без участия драйвера фс.

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

Винду или линукс выкинуть вообще даже для мягкого рилтайма ни категорически не годятся, QNX и ничего другого.

Нет. Под досом тоже можно. Или вообще взять какой-нибудь FreeRTOS (x86-32 оно умеет) или https://github.com/ReturnInfinity/BareMetal-OS (для x86-64)

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

Эмм, каким конкретно образом БД может сделать что-то быстрее по сравнению с прямой записью в файл?

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

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

Так тут никакой БД не надо. Открываем TCP сокет и срем в него байтами, а на другой стороне принимаем как-нибудь. Распределенная БД там будет, или RAID0 массив из кучи SSD - дело десятое

А если БД локальная, проблем со скоростью она никак не решит

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

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

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

если не флашить вручную, то оно само накопит и само сбросит

deep-purple ★★★★★
()
Ответ на: комментарий от user2132

Сделай себе такой-же комп, как у Заказчика и на нем отлаживай.

Да, винда ОЧЕ плохо работает в реальном времени без специальных приблуд на подобие RTAI (не помню, как там это называется).

Хочешь рилтайм - поставь хотя-бы DOS.

Ну и в два потока делай, естественно.

З.Ы.: Тред не читал.

shkolnick-kun ★★★★★
()
Ответ на: комментарий от user2132

Файл фиксированного размера, или он «Растет»?

Если «растет», то это не правильно…

shkolnick-kun ★★★★★
()
Ответ на: комментарий от anonymous

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

Если сделать нормально - будет всё гарантироваться. Можно и UDP пакетами, отправлять пакеты фиксированного размера, с порядковыми номерами и получением подтверждения на каждый полученный пакет (ACK). Всё это не подразумевает, что там на другой стороне будет БД в общепринятом смысле этого слова.

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

Все же просто - запускаешь 2 горутины, одна опрашивает датчик и скидывает данные в канал, другая наполняет буфер из канала и когда он заполнится записывает на диск. Ну и буфер канала побольше.

И как можно исправить эту проблему видимо с хардом ?

А может проблема в том что ты скидываешь жирный буфер в однопоточном софте на С++ в 2020? Да не, бред, конечно проблема с хардом.

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

1,2) пусть просто 1-ый будет приоритетнее, можно поставить даже режим THREAD_PRIORITY_TIME_CRITICAL или просто высокий доки 3) теоретически может, но зависит от условий, поковырявшись с настройками потоков и приоритетом ввода-вывода, можно привести к более менее стабильному состоянию 4) Зачем два процесса, если как правило 2 потока дешевле ? По поводу хуже-лучше будет по идее лучше, но это уприрается в опытность разработчика. Я рекомендую всё-таки, если опыта мало, съэкономить просто заведя два буфера и будить второй поток когда наполнится активный перейдя к записи во второй.

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

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

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

как вы задолбали нубы, там юсб сколько оно там мегабит древнее то? а диск сколько мегаБАЙТ? в секунду?

anonymous
()
Ответ на: комментарий от deep-purple

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

menangen ★★★★★
()

Тут без подробностей не решить. Виноват диск, можно покрутить настройки fs, виноват проц, крутить алгоритм

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