Я написал довольно большую программу на Фортране-90. Она прекрасно работала довольно долгое время, но сегодня я попытался повысить ее на ступеньку выше и увеличить размер проблемы (это исследовательский нестандартный FE-решатель), если это кому-нибудь поможет ...) Теперь я получаю сообщение об ошибке «переполнение стека», и, естественно, программа завершает работу, не давая мне ничего полезного для работы.
Программа начинается с установки всех соответствующих массивов и матрици после этого он выводит несколько строк статистики об этом в лог-файл.Даже с моей новой, более крупной проблемой, это работает нормально (хотя и немного медленно), но затем происходит сбой по мере того, как происходит «сокращение чисел».
Меня смущает то, что все в этой точке уже выделено (и это работало без ошибок).Я не совсем уверен, что такое стек (Википедия и несколько шагов здесь мало что сделали, так как у меня есть только базовые знания о «закулисной» работе компьютера).
Предположим, чтоНапример, у меня есть некоторые массивы, инициализированные как:
INTEGER,DIMENSION(64) :: IA
REAL(8),DIMENSION(:,:),ALLOCATABLE :: AA, BB
, которые после некоторых процедур инициализации (т.е. чтения входных данных из файла и т. Д.) Выделяются как (я храню некоторые целочисленные размеры для более легкой передачи подпрограммам в IAфиксированный размер):
ALLOCATE( AA(N1,N2) , BB(N1,N2) )
IA(1) = N1
IA(2) = N2
Это в основном то, что происходит в начальной части, и пока все хорошо.Но когда я тогда вызываю подпрограмму
CALL ROUTINE_ONE(AA,BB,IA)
И эта подпрограмма выглядит (ничего особенного):
SUBROUTINE ROUTINE_ONE(AA,BB,IA)
IMPLICIT NONE
INTEGER,DIMENSION(64) :: IA
REAL(8),DIMENSION(IA(1),IA(2)) :: AA, BB
...
do lots of other stuff
...
END SUBROUTINE ROUTINE_ONE
Теперь я получаю ошибку!Вывод на экран говорит:
forrtl: severe (170): Program Exception - stack overflow
Однако, когда я запускаю программу с отладчиком, она разрывается в строке 419 в файле с именем winsig.c
(не мой файл, но, вероятно, часть компилятора?).Кажется, что это часть подпрограммы с именем sigreterror:
, и это случай по умолчанию, который был вызван, возвращая текст Invalid signal or error
.К этому прилагается строка комментария, которая странным образом говорит: /* should never happen, but compiler can't tell */
...?
Итак, я предполагаю, что мой вопрос таков: почему это происходит и что на самом деле происходит?Я думал, что, пока я могу выделить всю необходимую память, у меня все будет хорошо?Создает ли вызов подпрограммы копии аргументов или просто указывает на них?Если ответ - копии, тогда я вижу, где может быть проблема, и если да: какие-либо идеи о том, как ее обойти?
Проблема, которую я пытаюсь решить, большая, но никак не безумная.Стандартные решатели FE могут справиться с большими проблемами, чем моя текущая.Я запускаю программу на Dell PowerEdge 1850, и операционной системой является Microsoft Server 2008 R2 Enterprise.Согласно systeminfo
в приглашении cmd
у меня 8 ГБ физической памяти и почти 16 ГБ виртуальной.Насколько я понимаю, сумма всех моих массивов и матриц не должна превышать 100 МБ - около 5,5 М integer(4)
и 2,5 М real(8)
(что, по моему мнению, должно составлять только около 44 МБ, но давайте будем честными)и добавьте еще 50 МБ для служебных данных).
Я использую компилятор Intel Fortran, интегрированный с Microsoft Visual Studio 2008.
Добавление некоторого фактического исходного кода для пояснения
! Update continuum state
CALL UpdateContinuumState(iTask,iArray,posc,dof,dof_k,nodedof,elm,&
bmtrx,detjac,w,mtrlprops,demtrx,dt,stress,strain,effstrain,&
effstress,aa,fi,errmsg)
- это фактический вызов подпрограммы.Большие массивы posc
, bmtrx
и aa
- все остальные по крайней мере на порядок меньше (если не больше).posc
равно INTEGER(4)
, bmtrx
и aa
равно REAL(8)
SUBROUTINE UpdateContinuumState(iTask,iArray,posc,dof,dof_k,nodedof,elm,bmtrx,&
detjac,w,mtrlprops,demtrx,dt,stress,strain,effstrain,&
effstress,aa,fi,errmsg)
IMPLICIT NONE
!I/O
INTEGER(4) :: iTask, errmsg
INTEGER(4) :: iArray(64)
INTEGER(4),DIMENSION(iArray(15),iArray(15),iArray(5)) :: posc
INTEGER(4),DIMENSION(iArray(22),iArray(21)+1) :: nodedof
INTEGER(4),DIMENSION(iArray(29),iArray(3)+2) :: elm
REAL(8),DIMENSION(iArray(14)) :: dof, dof_k
REAL(8),DIMENSION(iArray(12)*iArray(17),iArray(15)*iArray(5)) :: bmtrx
REAL(8),DIMENSION(iArray(5)*iArray(17)) :: detjac
REAL(8),DIMENSION(iArray(17)) :: w
REAL(8),DIMENSION(iArray(23),iArray(19)) :: mtrlprops
REAL(8),DIMENSION(iArray(8),iArray(8),iArray(23)) :: demtrx
REAL(8) :: dt
REAL(8),DIMENSION(2,iArray(12)*iArray(17)*iArray(5)) :: stress
REAL(8),DIMENSION(iArray(12)*iArray(17)*iArray(5)) :: strain
REAL(8),DIMENSION(2,iArray(17)*iArray(5)) :: effstrain, effstress
REAL(8),DIMENSION(iArray(25)) :: aa
REAL(8),DIMENSION(iArray(14)) :: fi
!Locals
INTEGER(4) :: i, e, mtrl, i1, i2, j1, j2, k1, k2, dim, planetype, elmnodes, &
Nec, elmpnodes, Ndisp, Nstr, Ncomp, Ngpt, Ndofelm
INTEGER(4),DIMENSION(iArray(15)) :: doflist
REAL(8),DIMENSION(iArray(12)*iArray(17),iArray(15)) :: belm
REAL(8),DIMENSION(iArray(17)) :: jelm
REAL(8),DIMENSION(iArray(12)*iArray(17)*iArray(5)) :: dstrain
REAL(8),DIMENSION(iArray(12)*iArray(17)) :: s
REAL(8),DIMENSION(iArray(17)) :: ep, es, dep
REAL(8),DIMENSION(iArray(15),iArray(15)) :: kelm
REAL(8),DIMENSION(iArray(15)) :: felm
dim = iArray(1)
...
И происходит сбой до последней строки выше.