![]() |
|
|
![]()
|
|
| popovda |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 290 Регистрация: 9.6.2006 Где: Москва Репутация: нет Всего: 6 |
Попросили тут простенькую прогу накидать на Фортране - для решения ДУ Бюргерса (с пересчетом по правилу Рунге):
Ну код вроде понятный. Так вот. Я привык писать в стиле Ф95/HPF/03, поэтому использовал не процедуру, а функцию, возвращающую массив (кстати, такая конструкция с точки зрения стандарта предпочтительнее). Переполнение стека. (Stack overflow) Но, я изменил в Project->Properties->Link->System->Stack Commite size до ГАРАНТИРОВАННЫХ 256 мб. (Это то же, что опция /STACK:nnnnn). А ему мало. Если организовать вызов не функции, а процедуры, то все равно при попытке организовать полноценный пересчет при перераспределении памяти для U1 и U2 наступает переполнение. Компилятор IFC 9.1.028. В чем дело?! -------------------- С уважением, Попов Д.А. |
|||
|
||||
| Cr@$h |
|
|||
![]() Исследователь ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1693 Регистрация: 3.4.2005 Где: Санкт-Петербург, Россия Репутация: 1 Всего: 41 |
Дима, привет. Попробуй размещаемые массивы в фунции спользовать: allocatable. Про Stack Commite size в 256 Мб я не уверен. Разве прогам под винды разрешено иметь такой стек? Не связывайся ты с этим стеком. Попробуй динамически размещать память. Кстати, а чем предпочтительнее оформлять как функцию, не как процедуру? Ведь при присвивании Ux = DU идёт копирование элементов результата в матрицу U1, когда как при сall DU(Mx, My, Ux) такого не будет. Обе процедуры будут чистыми, т.к. возвращают один результат. Странно, что при организации как процедуры тоже не работает, но там ведь не со стеком дело?..
|
|||
|
||||
| popovda |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 290 Регистрация: 9.6.2006 Где: Москва Репутация: нет Всего: 6 |
Как ни пробовал! Проблема в том, что должен быть выделен большой ДИНАМИЧЕСКИЙ массив. И выяснилось следующее - как только я пытаюсь создать такой массив - либо в основной программе, либо в подпрограмме, то массив пытается разместиться, но банально не хватает памяти. Ваш вариант тоже пробовал - тот же результат: во время выполнения переполнение стека и рекомендация увеличить размер, при 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 |
|
|||
![]() Исследователь ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1693 Регистрация: 3.4.2005 Где: Санкт-Петербург, Россия Репутация: 1 Всего: 41 |
Но стек не может переполняться, когда работаешь с динамическим размещением памяти. Работать будет, если внутри процедуры (подпрограммы или функции) убрать статические объявление real(8), dimension(0:Mt,0:Mx) :: U И результат функции можно сделать allocatable, тогда в стеке вообще ничего не будет практически. Плюс в головной программе поставить allocatable. но больше двух гигов в виндах просто так не выделить точно.
На счёт чистоты. Бог с ней. Есть чистые подпрограммы и функции. Меня фрагментация интересует больше. ArrayA = Func(ArrayB, ArrayC) call Func(ArrayA, ArrayB, ArrayC) Чем ДОЛЖНЫ отличаться эти два варианта. В первом случае выделяется динамически память для результата функции и потом эти значения копируются в ArrayA, который должен быть уже размещён или быть allocatable. После память освобождается. Во втором случае значения результата сразу заносятся в массив ArrayA, память не выделяется. Сводится ли это к одному и тому же коду при оптимизации, мне неизвестно? К тому же, это модельный пример, что делать со сложными ситуациями. Вернее, что делает с ними компилятор. P.S. И откуда это у фортраниста точки с запятой в конце строк? |
|||
|
||||
| Иванофф |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 8.9.2006 Репутация: нет Всего: нет |
в виндосе есть отображаемые файлы, и их может быть много, т.е. больше двух гигов с "виртуальной памятью" можно легко.
немного удивляет тема обсуждения и состав участников, или первое или второе должно быть другим |
|||
|
||||
| popovda |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 290 Регистрация: 9.6.2006 Где: Москва Репутация: нет Всего: 6 |
Вот. Я на эту тему
Интересовался у многих специалистов, таких как Серебряков или Горелик, так вот они однозначно сообщили, что если это нормально написанный компилятор, то такой синтаксис возвращаемого аргумента (через result) в функции как раз и предназначен для ОПТИМИЗАЦИИ по памяти. То есть указанные выше вызовы фактически эквивалентны. Фрагментации на мониторе памяти не наблюдалось. А про ";" в конце - привычка - я на первом курсе на Паскале писал, а потом со второго и по н.в. на C/С++. Просто у меня глаз режет, если ; не стоит. Психологически не воспринимаю код. Что до
то U - это автоматический массив. Не статический. Это сообщение отредактировал(а) popovda - 19.1.2008, 22:47 -------------------- С уважением, Попов Д.А. |
||||
|
|||||
| Cr@$h |
|
|||
![]() Исследователь ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1693 Регистрация: 3.4.2005 Где: Санкт-Петербург, Россия Репутация: 1 Всего: 41 |
Почему этот синтаксис ведёт к оптимизации, чем отличается от функции без reult и от чистой процедуры? Кстати, добил эту реализацию? Хм.. Его размер известен на этапе компиляции. Может память выделяется статическая? |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Fortran | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |