2015-12-31 2 views
7

Рассмотрите приложение 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++, чтобы действительно освободить память, которая не используется?

Спасибо.

+2

Может быть не полезно, но вы могли бы раскошелиться/EXEC дочерней программы, чтобы сделать большой расчет, то его куча будет «по-настоящему освобожден», когда он вышел. –

+4

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

+0

Почему у каждого узла нет единого процесса, который в цикле по всем ранкам будет: 1) получить ранг-ранг, 2) запустить отдельный поток, привязанный к другому ядру, с доступом к ранг-вектору? Тогда все основное использование памяти происходит в одном процессе, решая вашу проблему, сохраняя при этом параллелизм. –

ответ

1

Итак, после установки контекста этого вопроса: существует ли способ уменьшить размер кучи вручную на C++, чтобы действительно освободить память, которая не используется?

Это зависит от операционной системы, но, скорее всего, невозможно.

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

1

Кучи реализованы с использованием mmap на linux, и вам нужно будет использовать свою собственную кучу, которую вы можете полностью утилизировать и переделать.

munmap освободит место, требуемое.

Посмотрите на код в boost : pool для реализации, который позволит вам самостоятельно управлять лежащими в основе кучами.

По моему опыту очень трудно управлять контейнерами std с пользовательскими распределителями, поскольку они являются производными класса, а не производными от экземпляра.

0

Может ли разделяемая память решить вашу проблему (даже если вы не хотите использовать эту память)? Вы можете выделить блок разделяемой памяти в фазе «загрузки» и отключить ее после вычисления «myRankVector».

(см shmget, шмат, shmdt, shmctl (..., ipc_rmid,.))

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