Выделение самого большого буфера, не используя подкачку

В C/C++ в соответствии с Linux я должен выделить большой блок (на несколько гигабайтов) памяти для хранения данных реального времени от датчика, подключенного к порту Ethernet и данным потоковой передачи приблизительно в 110MB/s. Я хотел бы выделить самый большой возможный объем памяти, максимизировать длину последовательности данных, которую я могу сохранить. Однако я также должен удостовериться, что не будет никакого обмена с диском, так как получающаяся задержка и ограниченная пропускная способность доступа к диску заставляет датчик (очень ограниченный) буфер переполняться.

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

12
задан Chris Johnson 14 July 2010 в 10:54
поделиться

5 ответов

Ну, в Linux вы можете использовать mlock () / mlockall () для сохранения диапазона адресов в физической памяти и предотвращения его выгрузки. Процесс, использующий mlock, требует для этого нескольких привилегий, подробности есть у man mlock. Я не уверен в максимальном блоке mlock'able (он может отличаться от того, что кажется "свободным"), поэтому, вероятно, может помочь двоичный поиск (заблокируйте диапазон, если это не поможет, уменьшите размер области и т. Д.)

С другой стороны, 110 МБ / с не проблема для твердотельного накопителя. SSD на 60 ГБ со скоростью записи 280 МБ / с стоит около 200 долларов. Просто скопируйте данные датчика в небольшой буфер записи и передайте их на SSD.

9
ответ дан 2 December 2019 в 21:42
поделиться

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

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

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

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

0
ответ дан 2 December 2019 в 21:42
поделиться

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

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

Лучшее, что я могу придумать, это позволить пользователю настраивать, сколько памяти использовать для буферизации.

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

Заявленная свободная память на самом деле не является "свободной физической памятью". К сожалению.

или я могу более непосредственно взаимодействовать с менеджером виртуальной памяти linux?

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

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

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

  1. SysV разделяемая память. Обычно она не заменяется. См. man shmget.

  2. tmpfs - файловая система в памяти. Эта память была прикреплена к оперативной памяти, по крайней мере, в ранних версиях ядра 2.6, и поэтому не могла быть заменена. Чтобы использовать ее как память, создайте файл на tmpfs, запишите() что-нибудь в файл (чтобы заставить память быть фактически выделенной), а затем mmap() файл.

0
ответ дан 2 December 2019 в 21:42
поделиться

После выделения памяти вы можете

echo 0 > /proc/sys/vm/swappiness

попросить ядро ​​отдать предпочтение освобождению памяти из кеша вместо подкачки.

Всего 0,2 доллара

0
ответ дан 2 December 2019 в 21:42
поделиться

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

3
ответ дан 2 December 2019 в 21:42
поделиться