Увеличить размер стека

Я делаю вычисления с огромными массивами, и для некоторых из этих вычислений мне нужен увеличенный размер стека! Есть ли какие-либо недостатки установки размера стека на неограниченный (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-куча с покрытием) данные.

Другие вопросы по тегам