2012-07-04 6 views
7

Mam następujące pytanie: Jaki jest rzeczywisty narzut alokacji/deallocate oświadczenia w Fortran90 +? To znaczy, kilka średnich tablice są przydzielane wewnątrz pętli, jakFortran alokować/deallocate

do i = 1, 1000 
    allocate(tmp(20)) 
    tmp(1:20) = 1d0 
    call foo(tmp) 
    deallocate(tmp) 
end do 

Czy warto przydzielania pojedynczą tablicę pracy na podstawie maksymalnej wielkości w tym przypadku?

+1

To, czy są zauważalne oszczędności, zależy od tego, jak długo trwa "foo". Czy zmiana jest warta? Jest to albo kwestia opinii, albo należy zmierzyć czas pracy na kompilatorze i komputerze. Czy zmiana powoduje, że kod jest mniej czytelny? Jeśli tak, czy warto oszczędzić milisekundy środowiska wykonawczego? sekundy? –

Odpowiedz

6

Odkryłem, że dynamiczna alokacja tablicy w ciasnych pętlach może naprawdę spowolnić wykonywanie mojego kodu, z valgrind pokazującym, że duży procent cykli jest pobierany przez malloc i free. Więc jeśli foo jest bardzo szybką funkcją, to warto statycznie przydzielić tę tablicę. Łatwo jest dostrzec to obciążenie poprzez profilowanie przy użyciu funkcji wywoływania wywołania valgrind (może to być warte zmniejszenia rozmiaru problemu, ponieważ profilowane wykonanie może być co najmniej 10 razy wolniejsze).

W Fortran 2008 istnieje lepsze rozwiązanie tego typu problemów. Możesz zadeklarować swoje zmienne wewnątrz konstruktu block o rozmiarze określonym w czasie wykonywania. Powinno to znacznie ułatwić kompilatorowi przydzielenie zmiennej na stosie. Jednak nie używałem tego osobiście i nie jestem pewien, które kompilatory go obsługują.

+0

Uwaga: gfortran [obsługuje konstrukcje blokowe] (http://fortranwiki.org/fortran/show/Fortran+2008+status) – max

3

Narzut stosowania ALLOCATE i DEALLOCATE jest taka sama jak obciążania za pomocą malloc()free() i w C. W rzeczywistości większość Fortran realizacji (DE)ALLOCATE jak owijek malloc()/free() z pewnym dodatkiem księgowych, związane z każdym Fortran 90 tablicach.

Zazwyczaj lepiej jest przedalokować wystarczająco dużą tablicę podstawową i używać jej w ciasnych pętlach, zamiast stale przydzielać i zwalniać pamięć. Utrzymuje to również fragmentację sterty, co może prowadzić do problemów z alokacją w późniejszym czasie (bardzo rzadka sytuacja, ale dzieje się tak, zwłaszcza w przypadku kodów 32-bitowych).

+0

Dlaczego z kodami 32-bitowymi? – Rook

+2

Ponieważ kody 32-bitowe mają dostęp tylko do 2 GiB wirtualnej przestrzeni adresowej użytkownika (lub 4 GiB na OS X) współdzielonej między stertami, stosami i plikami mapowanymi w pamięci oraz ze źle pofragmentowaną stertą, może nie być wystarczająco dużej ciągłej przestrzeni do zapewnić dalsze przydziały dużych części. –