Re: [問題] 多維陣列 VS 一維陣列

看板Fortran作者 (挨)時間12年前 (2012/09/30 00:52), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串2/2 (看更多)
PS,我剛打完才發現我舉的例子中A是一維陣列,B是三維陣列,跟你原文相反... ※ 引述《iohan (iohan)》之銘言: : 假設 : integer A(10,10,10) : integer B(1000) : 結構上看起來用的記憶體要一樣 : 但是我聽到有種說法是A使用的記憶體會比B還來的大!? : 實際上是??? : 另外就是B的元素在記憶體上的分布是連續的這點不用質疑 : 那麼A呢?? 也是連續的阿 假設B陣列是2*2*2的大小 那B陣列在記憶體裡的排列順序,以FORTRAN來說就是 B(1,1,1)、B(2,1,1)、B(1,2,1)、B(2,2,1)、B(1,1,2)、B(2,1,2)、B(1,2,2)、B(2,2,2) 至於使用的記憶體大小,我不太確定 至少在儲存陣列內的元素值所占用的記憶體大小是一樣的 但是有聽說陣列會另外儲存陣列維度上下限的值 所以DEBUGER才能檢查出是否有呼叫到超出當初陣列宣告時大小的陣列元素 一維陣列只要記錄一個方向的上下限,以A陣列來講就是紀錄1跟1000兩個數字 三維陣列要記錄三個方向的上下限,以B來講就是紀錄1、10、1、10、1、10六個數字 所以說三維陣列用到的記憶體會比一維陣列大一些 不過這點我是真的很不確定,只是聽說的 因為實際上DEGUGER檢查程式裡是否有呼叫到超出陣列大小的元素的功能是可以關掉的.. 而且不同語言的可能作法也不同 : A(i,j,k) : 書上說按照 i -> j -> k 的順序下去讀是連續的 : 但是聽到上面第一種的說法害我開始懷疑B的連續性... : 假如真的是連續的 : 那麼A從1讀到1000 : 跟B從(1,1,1)讀到(10,10,10) : 速度上會有差?? ( 我在實際應用上的矩陣B可能是300*300*300 我自己認為還是有差的 因為所謂的陣列,其實只是一個指標而已 這個指標紀錄了陣列第一個元素在電腦記憶體裡的位址 我們呼叫陣列裡某個元素時,電腦只是根據這個陣列第一個元素的記憶體位址, 去計算出我們呼叫的元素在哪個記憶體位址裡,再去該記憶體位址取值 譬如你舉的例子,A是大小1000的一維陣列,B是大小10*10*10的三維陣列 對電腦而言,A這個變數,他記錄的是A(1)在記憶體裡的位址 B這個變數,他紀錄的則是B(1,1,1)在記憶體裡的位址 電腦要呼叫A(10)的值,他必須去計算A(10)所在的記憶體位址跟A(1)之間的關係 找到A(10)的記憶體位址,才能取出該記憶體位址的值,也就是A(10)的值 譬如如果我們同樣呼叫兩個陣列第一個元素所在位址的後面第500個元素 在A陣列就是A(500)的值,B陣列就是B(10,10,5)這個元素的值 理論上電腦一開始並不會知道A(500)跟B(10,10,5)都是陣列的第500個元素 那電腦在呼叫A(500)時, 因為電腦只記錄A(1)的位址,所以為了要得知A(500)所在的記憶體位址 他必須要做計算:A(500)所在記憶體位址 = A(1)記憶體位址 + 500 - 1 也就是一個加號的計算跟一個減法 而電腦要得知B(10,10,5)的記憶體位址,他必須要做計算: B(10,10,5)所在記憶體位址 = B(1,1,1)記憶體位址 + (5-1)*100 + (10-1)*10 + (10-1) 他必須要做2個乘法、3個加法、3個減法的計算,才能取得B(10,10,5)的值 在評估計算速度時, 為了簡化,我們通常會假設乘/除速度遠遠大於加減,所以只考慮乘/除的計算 因此可以很明顯看出,明明都是呼叫第500個元素的值, 三維陣列B所需要的時間會比一維陣列A多 因此理論上三維陣列的呼叫會比一維陣列慢 這是我自己的見解,若有誤,還請其他版友糾正 : 補個計概問題 : 請問一下電腦在執行指令時 : 不同的動作之間的速度比大概是怎麼樣的一個情況呢? : ex. : 浮點相乘: xxx Hz / s : 浮點相除: ooo Hz / s : 邏輯判斷: !!! Hz / s : 讀記憶體: ??? Hz / s : 寫記憶體: @@@ Hz / s : 掃記憶體: ... Hz / s -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.136.129.101

10/01 00:51, , 1F
感謝解答
10/01 00:51, 1F
文章代碼(AID): #1GPoSszb (Fortran)
討論串 (同標題文章)
文章代碼(AID): #1GPoSszb (Fortran)