Я разрабатываю 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() либо! Есть ли другой способ получить номер процессора или какой-либо идентификатор для процессора, чтобы я мог суммировать память, используемую для каждого процессора отдельно?
Или есть лучший способ решить эту проблему? Я открыт для предложений.
Вы пытались использовать системные ограничения (http://linux.die.net/man/2/setrlimit)? Вам придется устанавливать ограничения на каждый узел отдельно, но это не должно быть проблемой. – gawi
@gawi Я не знаком с getrlimit/setrlimit, поэтому я не пробовал. Спасибо что подметил это. Я предполагаю, что это позволило бы мне определить, приближается ли какой-либо данный процесс к пределу, установленному ядром, но разве еще нет возможности, чтобы ни один процесс не приближался к пределу, но в совокупности память, используемая всеми процессами, слишком высоко? – GentleEarwig
Да, этот метод позволяет вам устанавливать мягкие пределы ресурсов для текущего процесса и всех дочерних процессов. Однако, если он вам не подходит, сообщите мне, что вы используете для распространения ваших вычислений? MPI? И почему вы должны вручную проверять использование ресурсов? Как отметил Markhahn, это не ответственность пользователя, а система расписания. – gawi