Рассмотрите приложение MPI на основе двух шагов, которые мы будем называть Нагрузка и globalReduce. Просто для простоты программное обеспечение описывается как таковое, но происходит намного больше, так что это не просто проблема Map/Reduce.Уменьшение размера кучи программы на C++ после больших вычислений
В нагрузках шага, все ряды в каждом данном узле находятся в очереди, так что один и только один ранг имеет полный доступ к всем памяти узла. Причина этого дизайна возникает из-за того, что во время этапа загрузки имеется набор больших блоков ввода-вывода, которые считываются, и все они должны быть загружены в память до a Местное сокращение может иметь место. Мы будем называть это результатом местным сокращением именованной переменной myRankVector. После получения переменной myRankVector блоки ввода-вывода освобождаются. Переменная myRankVector сама использует небольшую память, поэтому пока ее создание может использовать все памяти, после завершения ранга нужно использовать только 2-3 ГБ для хранения myRankVector.
В стадии globalReduce в узле, ожидается, все ряды в узле загрузили их соответствующих globalReduce.
Итак, вот моя проблема, хотя я уверен, что нет никаких утечек памяти (я программирую с использованием общих указателей, я дважды проверял Valgrind и т. Д.), Я уверен, что куча остается расширенной даже после всех деструкторы выпустили блоки ввода-вывода. Когда следующий ранг в очереди приходит на работу, он начинает запрашивать большую память, как это делал предыдущий ранг, и, конечно же, программа убивает Linux, уступая «Out of memory: Kill process xxx (xxxxxxxx) score xxxx или жертвовать ребенком ". Понятно, почему это так, второй ранг в очереди хочет использовать всю память, но первый ранг остается с большой кучей.
Итак, после установки контекст этого вопроса: есть ли способ уменьшить размер кучи вручную на C++, чтобы действительно освободить память, которая не используется?
Спасибо.
Может быть не полезно, но вы могли бы раскошелиться/EXEC дочерней программы, чтобы сделать большой расчет, то его куча будет «по-настоящему освобожден», когда он вышел. –
Нам нужно будет увидеть код. Вопрос в том, почему второй ранг не использует повторно освобожденную память. –
Почему у каждого узла нет единого процесса, который в цикле по всем ранкам будет: 1) получить ранг-ранг, 2) запустить отдельный поток, привязанный к другому ядру, с доступом к ранг-вектору? Тогда все основное использование памяти происходит в одном процессе, решая вашу проблему, сохраняя при этом параллелизм. –