2011-07-07 9 views
11

Czy istnieje sposób tworzenia tablic o zmiennych rozmiarach w Fortranie na stosie? Allocate() nie działa dla mnie, ponieważ umieszcza tablicę na stercie. Może to prowadzić do problemów z równoległością (zobacz moje inne pytanie: OpenMP: poor performance of heap arrays (stack arrays work fine)). Oczywiście, pewne inteligentne zarządzanie pamięcią pozwoliłoby obejść ten problem, ale zarządzanie pamięcią w Fortranie brzmi głupio.Zmienne tablice rozmiarów w Fortranie bez przydziału()

Zasadniczo szukam dla Fortran równowartość co następuje: C:

scanf("%d", N); 
int myarray[N]; 

do ponownego iteracyjne: Nie chcę

Integer, PARAMETER :: N=100 
Integer, Dimension(N) :: myarray 

bo ten określa rozmiar tablicy przy kompilacji czas. Nie chcę też, ponieważ umieszcza tablicę na stercie.

Pomoc bardzo doceniana. Byłem bardzo szczęśliwy z tablicami Allocatable aż do ostatniego spotkania z problemem w powyższym pytaniu. Jeśli istnieje negatywna odpowiedź na to pytanie, bardzo bym docenił link do źródła.

Edycja: patrz komentarze do odpowiedzi M.S.B. Elegancki sposób robienia tego tylko stał się możliwy w Fortran 2008, i odbywa się to w konstrukcji block.

Odpowiedz

11

Fortran może automatycznie tworzyć tablice tylko z deklaracjami przy wejściu do podprogramów, o ile wymiary są znane w czasie wykonywania ... nie wymaga to deklarowania wymiarów jako atrybutów parametru, mogą to być argumenty, np. ,

subroutine MySub (N) 

integer, intent (in) :: N 
real, dimension (N) :: array 

jest ważna. Dlaczego więc nie zdecydować o rozmiarze "N" w programie głównym lub podprogramie, a następnie wywołać inny podprogram, aby kontynuować. Prawdopodobnie przy takim podejściu tablica będzie na stosie. Jak napisał @eriktous, standard języka Fortran nie określa tego zachowania. Niektóre kompilatory przełączają lokalne tablice na stos po określonym rozmiarze. Niektóre kompilatory udostępniają opcje kontrolowania tego zachowania. Umieszczenie dużych tablic na stercie prawdopodobnie zostanie przesłonięte rekursywnie lub OpenMP.

Można również przekazać tablicę alokacji jako rzeczywisty argument podprogramu, bez podania fałszywego argumentu podprogramu jako możliwego do przydzielenia. Co może nie pomóc w twoich obawach, ponieważ pierwotna tablica nadal będzie prawdopodobnie na kupce.

+1

Dzięki, M.S.B.! Tak samo ciężki jak w porównaniu z tablicą C 'int array [N]', robi to. – drlemon

+0

Możesz zrobić coś bliższego C, tj. Deklaracji w środku kodu, używając konstrukcji blokowej Fortran 2008. Zobacz na przykład str. 12 ftp://ftp.nag.co.uk/sc22wg5/N1701-N1750/N1729.pdf. Nie wiem, które kompilatory go obsługują, ani czy wspierają go przy pomocy OpenMP. –

+3

Mam tę konstrukcję w moim kodzie, jednak domyślam się, że domyślnie gfortran nadal umieszcza tablice na stercie, a teraz mam malloc w środku moich ciasnych pętli. Wydaje się, że potrzebna jest opcja "-fstack-arrays". – DaveP

5

Standard Fortran nie ma pojęcia stosu i sterty, więc będzie to zależne od implementacji (tj. Kompilatora). Patrząc na dokumenty dla np. gfortran, ma opcję

 
-frecursive 
    Allow indirect recursion by forcing all local arrays to be allocated on the stack. 

Inne kompilatory mogą mieć podobne opcje. Być może robi to, co chcesz.

+0

Dzięki, to ciekawy pomysł! Jednak tablice "lokalne", do których ma to zastosowanie, są tablicami utworzonymi w funkcjach, do których rozmiar tablicy jest przekazywany jako argument intent (in). W moich testach -frecursive nie miało wpływu na wyniki Allocate(), ale miało wpływ na to interesujące obejście: 'subroutine doit (n); liczba całkowita, zamiar (in) :: n; liczba całkowita, wymiar (1: n) :: myarray; ! bla; koniec podprogramu ... czytaj (*, *) n; call doit (n) ' W tym przypadku myarray wydaje się być na stosie zi bez -treści. Trochę zdemoralizowany, ale działa.Używam gcc 4.4.3 na x86_64. – drlemon

+0

@drlemon: Tak, bałem się, że ta konkretna opcja nie spełni dokładnie tego, czego potrzebujesz. Gcc 4.4.3 jest trochę stary, zwłaszcza z punktu widzenia Fortrana; Rozwój gfortran był (i nadal jest) dość aktywny. Jeśli to możliwe, możesz spróbować, czy nowsza wersja nadal wykazuje ten sam problem. Ponadto, gdybym był tobą, zadałbym twoje pytanie na liście dyskusyjnej gfortran. Ponieważ dotyczy to specyfiki implementacji, twórcy najlepiej wiedzą, co jest możliwe, a co nie. – eriktous

Powiązane problemy