2016-09-23 23 views
0

假設我們有一個維數爲(i,j)的數組A.我讀過的許多地方 - 正如Fortran語言是列爲主 - 環應編碼爲:應該在Fortran中使用比列更多的行來定義矩陣? (效率)

do j=1,n 
    do i=1,n 
    ! operate on A(i,j) 
    enddo 
enddo 

與此同時,我們應儘量減少循環的開銷,例如,如果N> M,那麼:

do j=1,m 
do i=1,n 
! ... 
enddo 
enddo 

比其他方式更有效率。作爲這兩個陳述的結果,如果我們想要定義一個維數爲(2,3)或(3,2)的矩陣,我們應該去第二個選項。我對嗎?我在任何地方都沒有看到這個聲明,我只是想知道我是否錯過了一些東西。謝謝

+1

我懷疑像這樣的優化很重要。 Fortran 2D數組是列主要的。如果它讓你感覺好一點,那就這樣做吧,但如果你能測量出顯着的差異,我會感到驚訝。 – duffymo

+1

它可能曾經有所作爲,但是通過優化編譯器足夠聰明來重新排列和展開循環,它今天可能並不重要。除非你看到像gprof這樣的性能分析工具出現瓶頸,否則你最好編寫更清晰的代碼並留下優化的編譯器。 – arclight

+1

甚至跟隨你的邏輯,它只適用於你可以任意轉置循環順序的例子。我的想法是,如果你經常在整行或列上操作,列更好,因爲它們是連續的。 – agentp

回答

1

因爲有一個剝離循環和一個尾循環,在循環次數很大時變得可以忽略不計,因此擁有較大的循環次數對於矢量化更好。 (https://en.wikipedia.org/wiki/Loop_splitting

但更重要的是:您應該將第一個索引作爲第一個索引來執行跨度爲1的循環,並將隨機訪問放置在其他維度中。這比循環計數重要得多。

其他重要的是如果你的第一個索引可以是矢量大小的倍數。例如,AVX指令在對應於4個雙精度浮點數的256位向量上運行。如果您的第一維數是4的倍數,並且您的數組是256位對齊的,則所有列將對齊,您將能夠獲得100%的矢量化潛力。 在你的例子中,將矩陣聲明爲(4,2)而不是(3,2)會更好!