Увеличить размер стека
Я делаю вычисления с огромными массивами, и для некоторых из этих вычислений мне нужен увеличенный размер стека! Есть ли какие-либо недостатки установки размера стека на неограниченный (ulimit -s unlimited
) в моем ~/.bashrc?
Программа написана на фортране (F77 и F90) и распараллелена с MPI. Некоторые из моих массивов содержат более 2E7 записей, и когда я использую небольшое количество ядер с MPI, происходит сбой segmentation fault
,
Размер массива остается неизменным на протяжении всего вычисления, поэтому я установил их для фиксированного значения:
real :: p(200,200,400)
integer :: ib,ie,jb,je,kb,ke
...
ib=1;ie=199
jb=2;je=198
kb=2;ke=398
call SOLVE_POI_EQ(rank,p(ib:ie,jb:je,kb:ke),R)
2 ответа
Установка размера стека на неограниченный, скорее всего, вам не поможет. Вы выделяете кусок размером 64 МБ в стеке и, скорее всего, заполняете его не сверху, а снизу.
Это важно, потому что ОС наращивает стек по мере продвижения. Всякий раз, когда он обнаруживает сбой страницы прямо под сегментом стека, он предполагает, что вам нужно больше места, и тихо вставляет новую страницу. Размер этой области триггера в пределах вашего адресного пространства ограничен, и я сомневаюсь, что она больше 64 МБ. Поскольку ваши индексные переменные, вероятно, размещены ниже вашего массива в стеке, доступ к ним уже делает скачок 64 МБ, который убивает ваш процесс.
Просто сделай свой массив allocatable
добавить соответствующий allocate()
Скажите, и вы должны быть в порядке.
Размер стека никогда не бывает неограниченным, поэтому у вас все равно будут некоторые сбои. И ваш код по-прежнему не будет переносимым на системы Linux с меньшими (или обычными) стеками.
Кстати, вы должны объяснить, какие программы вы используете, показать некоторый исходный код.
Если кодирование на C++, использование стандартных контейнеров должно помочь (относительно фактического потребления стека). Например, локальный (выделенный стек) std::vector<int> v(10000);
(вместо int v[10000];
) его данные размещаются в куче (и освобождаются деструктором при выходе из блока, определяющего его)
Было бы намного лучше улучшить ваши программы, чтобы избежать чрезмерного потребления стека. Потребность в большом количестве стекового пространства - это действительно ошибка, которую вы должны попытаться исправить. Типичное эмпирическое правило заключается в том, чтобы кадры вызовов были меньше нескольких килобайт (поэтому выделяйте любые большие данные в куче).
Вы могли бы также рассмотреть возможность использования консервативного сборщика мусора Boehm: вы бы использовали GC_MALLOC
вместо malloc
(и вы бы выделите большую структуру данных, используя GC_MALLOC
) но вам не придется беспокоиться о free
ваши (GC-куча с покрытием) данные.