2013-07-14 2 views
0

Я разрабатываю C++-код в Linux, который может закончиться нехваткой памяти, вступить в swap и значительно замедлиться, а иногда и сбой. Я хотел бы предотвратить это, разрешив пользователю указать ограничение на долю общей системной памяти, которую может использовать процесс. Если программа должна превышать этот предел, тогда код может выводить некоторые промежуточные результаты и прекращать чистоту.Как предотвратить мой параллельный код, используя всю доступную системную память?

Я могу определить, сколько памяти используется, читая размер резидентного набора из/proc/self/stat. Затем я могу суммировать это во всех параллельных процессах, чтобы дать мне общее использование памяти для программы.

Общая доступная системная память может быть получена при вызове sysconf (_SC_PHYS_PAGES) (см. How to get available memory C++/g++?). Однако, если я запускаю параллельный кластер, то, вероятно, эта цифра даст мне только общую память для текущего узла кластера. Например, я могу запустить 48 процессов по 4 узлам кластера (каждый с 12 ядрами).

Итак, мой реальный вопрос: как узнать, какой процессор работает на данный процесс? Затем я мог бы суммировать память, используемую процессами, запущенными на одном узле кластера, и сравнить это с доступной памятью на этом узле и завершить работу программы, если она превышает указанный процент на любом из узлов, на которых запущена программа. Я использовал бы sched_getcpu() для этого, но, к сожалению, я компилирую и запускаю систему с версией 2.5 glibc, а sched_getcpu() была введена только в glibc 2.6. Кроме того, поскольку кластер использует на старой ОС Linux (версия 2.6.18), я не могу использовать syscall() для вызова getcpu() либо! Есть ли другой способ получить номер процессора или какой-либо идентификатор для процессора, чтобы я мог суммировать память, используемую для каждого процессора отдельно?

Или есть лучший способ решить эту проблему? Я открыт для предложений.

+0

Вы пытались использовать системные ограничения (http://linux.die.net/man/2/setrlimit)? Вам придется устанавливать ограничения на каждый узел отдельно, но это не должно быть проблемой. – gawi

+0

@gawi Я не знаком с getrlimit/setrlimit, поэтому я не пробовал. Спасибо что подметил это. Я предполагаю, что это позволило бы мне определить, приближается ли какой-либо данный процесс к пределу, установленному ядром, но разве еще нет возможности, чтобы ни один процесс не приближался к пределу, но в совокупности память, используемая всеми процессами, слишком высоко? – GentleEarwig

+0

Да, этот метод позволяет вам устанавливать мягкие пределы ресурсов для текущего процесса и всех дочерних процессов. Однако, если он вам не подходит, сообщите мне, что вы используете для распространения ваших вычислений? MPI? И почему вы должны вручную проверять использование ресурсов? Как отметил Markhahn, это не ответственность пользователя, а система расписания. – gawi

ответ

0

Грамотно выполняемый кластер будет помещать ваши рабочие места под определенные пределы ресурсов (RLIMIT_AS или cgroups). Вы можете сделать это сами, позвонив по телефону setrlimit(RLIMIT_AS,...). Я думаю, что вы чрезмерно беспокоитесь о sysconf, так как в общем кластере нет оснований полагать, что ваш код должен использовать хотя бы фиксированную долю физического объема памяти. Вместо этого вы должны выбрать разумную потребность в памяти (если ваш кластер не предоставляет один-самый планировщик, планирование памяти достаточно хорошо.) Даже если вы настаиваете на том, чтобы делать это самостоятельно, автоматическое определение размера, вам не нужно знать о какие ядра используются: просто выяснить, сколько копий вашего процесса находится на узле, и разделить соответствующим образом. (вам нужно будет выяснить, какой узел (хост) каждый процесс запущен, конечно.)

Стоит отметить, что ядро ​​RLIMIT_AS, а не RLIMIT_RSS. И когда вы нажмете этот предел, новые распределения не удастся.

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

+0

Да, как вы указываете, мне нужно выяснить, на каком узле (хосте) работает каждый процесс - вот что я застрял! Какие-либо предложения? Я не пытаюсь выделить кусок памяти для моей программы для запуска. Я не могу слишком подробно разбираться в своем алгоритме, я боюсь, но я по существу уточняю треугольную поверхностную сетку на основе определенных критериев , Тем не менее, я не знаю apriori, насколько прекрасна поверхность. Я выполнил ограничение на количество лиц, но я хотел сделать что-то более интеллектуальное, основанное на доступных аппаратных ресурсах. В любом случае, спасибо за вашу помощь. – GentleEarwig

Смежные вопросы