Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

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

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

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

Тем не менее, мне также нужно убедиться, что не будет обмена с дисками

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

  • Общая память SysV. Обычно он не заменяется. См. man shmget.

  • tmpfs - файловая система в памяти. Память была прикреплена к ОЗУ как минимум в ранних версиях ядра 2.6 и, следовательно, не была заменена. Чтобы использовать его в качестве памяти, создайте файл на tmpfs, write() что-нибудь в файле (чтобы принудительно назначить память), а затем файл mmap().

Ответ 5

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

echo 0 > /proc/sys/vm/swappiness

Чтобы ядро ​​предпочитало возвращать память из кэша вместо замены.

Только мои $0.2