| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Fortran > [General] Почему переполнение стека в IFC?! |
| Автор: popovda 25.12.2007, 15:13 | ||
Попросили тут простенькую прогу накидать на Фортране - для решения ДУ Бюргерса (с пересчетом по правилу Рунге):
Ну код вроде понятный. Так вот. Я привык писать в стиле Ф95/HPF/03, поэтому использовал не процедуру, а функцию, возвращающую массив (кстати, такая конструкция с точки зрения стандарта предпочтительнее). Переполнение стека. (Stack overflow) Но, я изменил в Project->Properties->Link->System->Stack Commite size до ГАРАНТИРОВАННЫХ 256 мб. (Это то же, что опция /STACK:nnnnn). А ему мало. Если организовать вызов не функции, а процедуры, то все равно при попытке организовать полноценный пересчет при перераспределении памяти для U1 и U2 наступает переполнение. Компилятор IFC 9.1.028. В чем дело?! |
| Автор: Cr@$h 4.1.2008, 19:09 |
| Дима, привет. Попробуй размещаемые массивы в фунции спользовать: allocatable. Про Stack Commite size в 256 Мб я не уверен. Разве прогам под винды разрешено иметь такой стек? Не связывайся ты с этим стеком. Попробуй динамически размещать память. Кстати, а чем предпочтительнее оформлять как функцию, не как процедуру? Ведь при присвивании Ux = DU идёт копирование элементов результата в матрицу U1, когда как при сall DU(Mx, My, Ux) такого не будет. Обе процедуры будут чистыми, т.к. возвращают один результат. Странно, что при организации как процедуры тоже не работает, но там ведь не со стеком дело?.. |
| Автор: popovda 5.1.2008, 17:59 |
| Как ни пробовал! Проблема в том, что должен быть выделен большой ДИНАМИЧЕСКИЙ массив. И выяснилось следующее - как только я пытаюсь создать такой массив - либо в основной программе, либо в подпрограмме, то массив пытается разместиться, но банально не хватает памяти. Ваш вариант тоже пробовал - тот же результат: во время выполнения переполнение стека и рекомендация увеличить размер, при 2 Гб ОЗУ на компе. Банально, но когда столкнулся с такой же хреновиной года 2 назад под CVF - изменение размера стека спасло. Дал директивно 200 мб и все.... Что до чистых процедур/функций. Я понимаю, что может возникать фрагментация памяти. Поэтому я давно поставил с десяток экспериментов - фрагментация есть только в дебаге, т.е. при отключенной оптимизации. Как только включена оптимизация хотя бы по памяти, то проблем с фрагментацией памяти нет. Да и в принципе разница между объявлениями function FuncName(...tra-ta-ta...) result(res) и subroutine FuncName(...tra-ta-ta...,res) для компилятора (с оптимизацией!!!) нет - все равно массив возвращается через адрес 1-го элемента. А про хитрости с оптимизацией я указал. Кстати, на NAG Fortran 5.1 код запахал без проблем... А вот читабельность кода выше. Что до чистых подпрограмм, то чистая процедура и чистая функция пришли из HPF, как и конструкция furnctoin ... result(res) - именно с целью высокой оптимизации в модели общей памяти для чистых подпрограмм. |
| Автор: Cr@$h 8.1.2008, 20:33 |
| Но стек не может переполняться, когда работаешь с динамическим размещением памяти. Работать будет, если внутри процедуры (подпрограммы или функции) убрать статические объявление real(8), dimension(0:Mt,0:Mx) :: U И результат функции можно сделать allocatable, тогда в стеке вообще ничего не будет практически. Плюс в головной программе поставить allocatable. но больше двух гигов в виндах просто так не выделить точно. На счёт чистоты. Бог с ней. Есть чистые подпрограммы и функции. Меня фрагментация интересует больше. ArrayA = Func(ArrayB, ArrayC) call Func(ArrayA, ArrayB, ArrayC) Чем ДОЛЖНЫ отличаться эти два варианта. В первом случае выделяется динамически память для результата функции и потом эти значения копируются в ArrayA, который должен быть уже размещён или быть allocatable. После память освобождается. Во втором случае значения результата сразу заносятся в массив ArrayA, память не выделяется. Сводится ли это к одному и тому же коду при оптимизации, мне неизвестно? К тому же, это модельный пример, что делать со сложными ситуациями. Вернее, что делает с ними компилятор. P.S. И откуда это у фортраниста точки с запятой в конце строк? |
| Автор: Иванофф 9.1.2008, 00:34 |
| в виндосе есть отображаемые файлы, и их может быть много, т.е. больше двух гигов с "виртуальной памятью" можно легко. немного удивляет тема обсуждения и состав участников, или первое или второе должно быть другим |
| Автор: popovda 19.1.2008, 22:45 | ||||
Вот. Я на эту тему
Интересовался у многих специалистов, таких как Серебряков или Горелик, так вот они однозначно сообщили, что если это нормально написанный компилятор, то такой синтаксис возвращаемого аргумента (через result) в функции как раз и предназначен для ОПТИМИЗАЦИИ по памяти. То есть указанные выше вызовы фактически эквивалентны. Фрагментации на мониторе памяти не наблюдалось. А про ";" в конце - привычка - я на первом курсе на Паскале писал, а потом со второго и по н.в. на C/С++. Просто у меня глаз режет, если ; не стоит. Психологически не воспринимаю код. Что до
то U - это автоматический массив. Не статический. |