mmap и медленные передачи DMA

У меня есть процесс, который считывает данные с аппаратного устройства с использованием DMA-передач со скоростью ~ 4 * 50 Мбайт / с и в то же время данные обрабатываются, сжимаются и записываются в файл с отображением 4 ТБ.

Каждая передача DMA должна (и делать в среднем) менее 20 мс. Тем не менее, несколько раз каждые 5 минут передача DMA может занять до 300 мс, что является огромной проблемой.

Мы полагаем, что это может быть связано с тем, что ядро ​​очищает грязные карты памяти на диске. Поскольку, если мы прекращаем запись в сопоставленную память, DMA переносит длительности точно. Однако мы смущены тем, как / почему это может повлиять на передачу DMA и есть ли способ избежать этого?

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

В настоящее время мы проводим тестирование на Arch Linux с ядром 4.1.10 lts, ​​но мы также пробовали Ubuntu 14.04 с наиболее худшими результатами. Аппаратное обеспечение – рабочая станция HP z820, 32 ГБ оперативной памяти и двойной Xeon E5-2637 @ 3,50Ghz ( http://www8.hp.com/h20195/v2/GetPDF.aspx/c04111177.pdf ).

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

  • Ext4 демонстрирует неожиданную дисперсию латентности записи по сравнению с ext2
  • Как кеш страниц отображается в ядре на 64-разрядных архитектурах x86?
  • Могу ли я добавить / proc / self?
  • Понимание MMAP
  • Режим объекта Grsecurity x
  • Если я mmap файл из tmpfs, будет ли он удвоить использование памяти?
  • Использование общей памяти через tmpfs и NUMA на x86_64 / Linux
  • Поведение памяти mmap'd на давление памяти
  • 3 Solutions collect form web for “mmap и медленные передачи DMA”

    В Linux есть некоторые варианты в реальном времени , хотя это не ядро ​​реального времени как таковое. Это позволяет процессу требовать, чтобы он был запланирован перед процессами, отличными от реального времени, как только он был готов, и держаться за процессор до тех пор, пока это необходимо.

    По умолчанию процессам присваивается политика планирования SCHED_OTHER. Вы можете установить это в SCHED_FIFO в реальном времени для данного запущенного pid с chrt -f -p prio pid или префикс команды с chrt -f prio при ее запуске. Приоритет prio не зависит от обычных процессов и используется только тогда, когда процессы реального времени конкурируют за ресурсы. ps показывает эти приоритеты как отрицательные значения (например, -21 для реального времени prio 20).

    ionice --class 1 -p pid также может помочь планировать ваш процесс с предпочтительной очередью в режиме реального времени.

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

    Если есть паузы, вы можете заставить ядро очистить буферы и кеш во время них, поэтому это действие не будет мешать передаче DMA. Кроме того, вы можете настроить ваше ядро ​​на интервал BDFLUSHR в 1 секунду, так что у ядра меньше данных для записи каждый раз, когда он решает сбросить буферы.

    Если вам необходимо обеспечить непрерывную работу, вам понадобится ОЗУ с большим количеством каналов, чтобы процессор и ваше устройство могли одновременно получать доступ к памяти (как оказалось, у вас уже есть 4-канальный контроллер памяти). Убедитесь, что вы настроили свою оперативную память в режиме unganged , если этот параметр доступен. Убедитесь, что вы установили аналогичные модули DRAM в 4 слота, соответствующие каналам памяти, так что ваш контроллер памяти может фактически работать в 4-канальном режиме.

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

     /proc/sys/vm/dirty_background_bytes:50000000 /proc/sys/vm/dirty_bytes:4000000000 /proc/sys/vm/dirty_expire_centisecs:100 /proc/sys/vm/dirty_writeback_centisecs:20 

    (Подробнее см. https://www.kernel.org/doc/Documentation/sysctl/vm.txt .)

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

    Linux и Unix - лучшая ОС в мире.