2012-07-12 48 views
2

這個問題是類似於已經被問earlier但我認爲內存分頁不考慮。所以,我在這裏再次提出類似的問題:在C++函數,指針VS索引數組

// version 1 
int nums[100]; 
int* pNum = nums; 
for(int i=0;i<100;i++,pNum++){ 
    foo(pNum); 
} 

// version 2 
for(int i=0;i<100;i++){ 
    foo(nums[i]); 
} 

哪個版本會更快?以前,據說生成的彙編代碼會非常相似,因爲兩個版本都需要增加內存地址的位置,但是考慮到一個非常大的數組,內存分頁性能是否會發生顯着變化?由於其中一個需要長時間移位,但另一個需要從陣列的基本內存地址移位?我知道這是非常依賴平臺/編譯器,但仍然想知道人們的常見做法,特別是處理像圖像處理或科學計算這樣的大數據類型?謝謝。

+0

嘗試定時既看到自己。但我警告說,現代編譯器非常有能力將一種形式轉換爲另一種形式。因此可能很難進行基準測試。 – Mysticial 2012-07-12 01:17:11

+0

你不應該擔心這樣的小細節。無論您如何編寫,編譯器都足夠聰明,可以優化這一點。而且,像這樣的微觀優化幾乎普遍浪費時間;通常會有更大的低效率來源。 – templatetypedef 2012-07-12 01:17:32

+0

事實上,這是一個採訪問題,我已經說了一些類似於@templatetypedef的內容,但我認爲這對於芯片組製造商來說確實很重要。 – tartar 2012-07-12 01:21:36

回答

5

普遍的共識是,對於基本類型,沒有什麼區別。大多數編譯器會爲此生成完全相同的代碼(假定您的意思是foo(*pNum))。

+0

如果它不產生相同的代碼,我會想象它更可能以「陷入困境」的第1版,因爲它不是寫代碼的典型方式,並利用指針,它的編譯器偶爾也會有麻煩的。 – helloworld922 2012-07-12 01:27:02

+0

你認爲緩存未命中/內存分頁?假設pNum當前指向地址base_address + 10 * sizeof(int),在這種情況下,可能CPU可能認爲從base_address + 10 * sizeof(int)緩存到30 * sizeof(int)將是一個好主意。但是,對於帶有索引的數組的情況,沒有暗示處理數組的哪一部分? – tartar 2012-07-12 01:28:48

+1

大多數編譯器都可以選擇輸出asm代碼(例如,在gcc上爲-S)。 gcc與-O1生成*完全相同的代碼。 – vanza 2012-07-12 01:29:25

1

我知道這是很平臺/編譯器相關的

究竟

,但還是想知道人們的普遍做法,尤其是對於大型的數據類型,如圖像處理或科學工作計算?謝謝。

兩種做法是常見的,如使用載體和迭代器。你擔心的事情可能是無關緊要的。使用任何最好的方式表達你在思維上對算法進行可視化的方式,這樣可以更容易地進行正確的維護和演變。