Оптимизация памяти для дочерних процессов - PullRequest
0 голосов
/ 06 сентября 2010

Я работаю на Linux для процессора ARM для кабельного модема.Я написал инструмент, который отправляет / отправляет настроенные UDP-пакеты, используя необработанные сокеты.Я формирую пакет с нуля, чтобы у нас была возможность играть с разными вариантами.Этот инструмент предназначен в основном для стресс-тестирования маршрутизаторов.

У меня на самом деле создано несколько интерфейсов.Каждый интерфейс будет получать IP-адреса с использованием DHCP.Это сделано для того, чтобы модем вел себя как виртуальное абонентское оборудование (vcpe).

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

Я запускаю эти процессы, используя fork и исключая процессы инициализации модема.

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

Я пробовал следующее:

Я всегда предполагал, что передача большего количества кода в общие библиотеки поможет.Поэтому, когда я попытался переместить многие функции в разделяемую библиотеку и сохранить минимальный код в процессах, к моему удивлению это не имело никакого значения.Я также удалил все массивы и заставил их использовать кучу.Однако это не имело никакого значения.Это может быть потому, что процессы работают непрерывно, и не имеет значения, стек это или куча?Я подозреваю, что процесс, от которого я называю разветвление, огромен, и это является причиной того, что процессы, которые я делаю, являются огромными.Я не уверен, как еще я мог пойти.скажем, процесс A огромен -> я запускаю процесс B, разветвляясь и выполняя функции.B наследует область памяти A.Так что теперь я делаю это -> A запускает C, который запускает inturn B, также не поможет, так как C все еще наследует A ?.Я использовал vfork как альтернативу, которая тоже не помогла.Я удивляюсь, почему.

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

Ответы [ 3 ]

2 голосов
/ 06 сентября 2010

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

В противном случае:

  1. Как вы измеряете использование памяти? Некоторые методы не дают точных результатов.
  2. Убедитесь, что у вас нет утечек памяти. например с Valgrind в Linux x86.
  3. Вы можете попробовать запустить разные тестеры в одном процессе, как разные потоки, или даже мультиплексировать в одном потоке - так как ограничивающим фактором должна быть сеть?
  4. exec () сократит объем памяти процессов, когда новое выполнение получит новую карту памяти.
  5. Если вы не можете добавить физическую память, то, возможно, вы можете добавить swap, может быть, просто для тестирования?
1 голос
/ 06 сентября 2010

Что может случиться, так это то, что вызов fork в процессе A требует значительного объема RAM + swap (если есть). Таким образом, когда вы вызываете fork () из этого процесса, ядро ​​должно зарезервировать достаточно оперативной памяти и выполнить подкачку, чтобы дочерний процесс имел свою собственную копию (фактически, копирование при записи) доступной для записи частной памяти родительского процесса, а именно его стек и кучу , Когда вы вызываете exec () из дочернего процесса, эта память больше не нужна, и у вашего дочернего процесса может быть свой собственный, меньший частный рабочий набор.

Итак, первое, что нужно убедиться, это то, что у вас не более одного процесса одновременно в состоянии между fork () и exec (). В этом состоянии дочерний процесс должен иметь копию своего виртуального пространства памяти родительского процесса.

Во-вторых, попробуйте использовать настройки overcommit, которые позволят ядру зарезервировать больше памяти, чем фактически существует. Это / proc / sys / vm / overcommit *. Вы можете избежать использования overcommit, потому что вашим дочерним процессам нужно только дополнительное пространство ВМ, пока они не вызовут exec, и они не должны касаться дублированного адресного пространства родительского процесса.

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

1 голос
/ 06 сентября 2010

Технически не отвечая на ваш вопрос, но предлагая несколько альтернативных решений:

Если вы используете Linux, вы рассматривали возможность использования pktgen ? Это гибкий инструмент для отправки UDP-пакетов из ядра настолько быстро, насколько позволяет интерфейс. Это намного быстрее, чем инструмент пользовательского пространства.

ой и бесстыдная вилка. Я создал инструмент для многопоточного тестирования сети , который можно использовать для рассылки спама по сети с помощью пакетов UDP. Он может работать в многопроцессорном режиме (с помощью fork) или в многопоточном режиме (с помощью pthreads). Pthreads может использовать меньше оперативной памяти, поэтому может быть лучше использовать. Во всяком случае, стоит взглянуть на источник, поскольку я потратил много лет на улучшение этого кода, и он смог сгенерировать достаточно пакетов для насыщения интерфейса 10 Гбит / с.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...