2011-07-07 41 views
11

有沒有辦法在Fortran 上創建可變大小的數組?? Allocate()不適用於我,因爲它將數組放在堆上。這可能會導致並行化問題(請參閱我的其他問題: OpenMP: poor performance of heap arrays (stack arrays work fine))。當然,一些聰明的內存管理會解決這個問題,但Fortran中的內存管理聽起來很愚蠢。Fortran中可變大小的數組沒有分配()

從本質上講,我期待在C以下的Fortran語言相同的:

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

再次重申:我不想

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

,因爲這將決定在編譯數組的大小時間。我也不想要

Integer, Dimension(:), Allocatable :: myarray 
read(*,*) N 
Allocate(myarray(1:N)) 

因爲它將數組放在堆上。

非常感謝。直到我最近遇到上述問題中的問題,我纔對Allocatable陣列感到非常滿意。如果對這個問題有一個否定的答案,我會非常感謝這個來源的鏈接。

編輯:查看對M.S.B的答覆的評論。在Fortran 2008中,只有這樣做纔是可行的,並且它的構造是block

回答

11

Fortran語言可以自動創建數組只是在進入子程序聲明,只要尺寸在運行時知道...這並不需要的尺寸要聲明參數屬性,他們可以是參數,例如,

subroutine MySub (N) 

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

有效。那麼爲什麼不在主程序或某個子程序中決定你的大小「N」,然後調用另一個子程序繼續。可能與這種方法陣列將在堆棧上。正如@eriktous所寫,Fortran語言標準沒有指定這種行爲。一些編譯器將本地數組切換到超過特定大小的堆。一些編譯器提供了控制這種行爲的選項。將大數組放在堆上可能會被遞歸或OpenMP覆蓋。

您也可以通過可分配數組作爲實際參數傳遞給子例程沒有子程序的僞參數被聲明爲可分配的。這可能無助於您的擔憂,因爲原始數組仍然可能堆積如山。

+1

謝謝,M.S.B.!與C的int數組[N]相比,它的重要性在於它。 – drlemon

+0

使用Fortran 2008的塊構造,您可以更接近於C,即代碼中間的聲明。參見例如,p。 12 ftp://ftp.nag.co.uk/sc22wg5/N1701-N1750/N1729.pdf。我不知道哪些編譯器支持這個,或者他們是否支持OpenMP。 –

+3

我在我的代碼中有這個構造,但是我注意到,默認情況下,gfortran仍然將數組放在堆上,現在我在緊密循環的中間有malloc。看起來需要選項「-fstack-arrays」。 – DaveP

5

Fortran標準沒有堆棧和堆的概念,所以這將取決於實現(即編譯器)。查看文檔,例如gfortran,它有一個選項

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

其他編譯器也可能有類似的選項。也許這是你想要的。

+0

謝謝,這是一個有趣的想法!然而,適用於此的「Local」數組是在函數中創建的數組,其數組大小作爲intent(in)參數傳遞給它。在我的測試中,-frecursive對分配()的結果沒有影響,但確實對這個有趣的解決方法的效果: '子程序DOIT(N);整數,意圖(in):: n;整數,維(1:n):: myarray; !等等結束子程序... read(*,*)n; 呼叫DOIT(N)' 在這種情況下,myarray中似乎得到堆棧與不-frecursive上。有點變態,但伎倆。我在x86_64上使用gcc 4.4.3。 – drlemon

+0

@drlemon:對,我擔心這個特殊的選項並不能完全滿足你的需求。海灣合作委員會4.4.3是古老的,特別是從Fortran的角度來看; gfortran的發展一直是(現在仍然)非常活躍。如果可能的話,你可以試試更新的版本是否仍然存在相同的問題。另外,如果我是你,我會在gfortran郵件列表上提問你的問題。由於這涉及到具體的實現,開發人員最好知道什麼是可能的,哪些不可以。 – eriktous