2014-09-28 116 views
1

我有兩個函數的代碼,一個分配一個靜態數組,一個分配一個數組在堆棧上。這些函數運行很多次,並計算它們的執行時間。堆棧分配始終(稍微)比靜態分配更快。我的印象是,由於靜態變量被運行時,它會執行比是在棧上分配的陣列更快之前勢必定時數組靜態數組分配vs堆棧中的數組C

#include <stdio.h> 

#include <stdlib.h> 
#include <time.h> 
#define MAX_ARRAY 8192 

void statArray() 
{ 
static int statArray[MAX_ARRAY]; 
} 
void stackArray() 
{ 
int stackArray[MAX_ARRAY]; 
} 

int main(int argc, char * argv[]) { 
    clock_t start, end; 
    double staticTime, stackTime; 
    int i; 
    int comparisons = 5000000; 

    start = clock(); 
    for (i = 0; i < comparisons; i++) { 
      statArray(); 
    } 
    end = clock()-start; 
    staticTime = (double)end/CLOCKS_PER_SEC; 

    start = clock(); 
    for (i = 0; i < comparisons; i++) { 
      stackArray(); 
    } 
    end = clock() - start; 
    stackTime = (double) end/CLOCKS_PER_SEC; 

感謝

拆卸statArray

0x0000000000400594 <+0>: push %rbp 
    0x0000000000400595 <+1>: mov %rsp,%rbp 
    0x0000000000400598 <+4>: leaveq 
    0x0000000000400599 <+5>: retq 

拆卸堆棧陣列

0x000000000040059a <+0>: push %rbp 
    0x000000000040059b <+1>: mov %rsp,%rbp 
    0x000000000040059e <+4>: sub $0x7f88,%rsp 
    0x00000000004005a5 <+11>: leaveq 
    0x00000000004005a6 <+12>: retq 
+0

爲了知道發生了什麼,您將不得不反彙編這兩個函數(statArray和stackArray)。我的猜測是stackArray分配被優化器刪除。 – Steen 2014-09-28 20:24:01

+0

編譯器可能會利用指令或緩存,這些指令允許更快地訪問堆棧上的空間,而不是訪問內存中其他位置的空間。預先計算的地址在理論上更快,當然,但這可能是一次加載寄存器與陣列的基地址的差異。正如@Steen所說,如果你想知道發生了什麼,請查看生成的代碼。 (很好的例子,爲什麼你不應該擔心微代碼的優化,直到你知道什麼是重要的,重點在算法,而不是欺騙,直到你有痕跡,並知道什麼欺騙將是值得的努力。) – keshlam 2014-09-28 20:57:54

+0

@keshlam它是來自Sebesta的編程語言概念的練習,它不是用於任何形式的微觀優化,而是理解堆棧,堆和靜態分配之間的概念。我的結果與我的期望不同,所以我想知道結果是錯誤的還是我的期望。也就是說,我已將反彙編的函數添加到 – IMerin 2014-09-28 21:06:16

回答

3

正如你可以看到在議會裏sting,statArray是一個空函數,並且stackArray包含單個分配指令(sub rbp,imm)。該指令的時間效應可能被序言/結語指令的延遲所隱藏,並且只能用CPU溫度計來測量差異。您遇到的實際差異是由於時間測量誤差很小,如果您交換代碼塊的順序,則可能會發生變化。

編輯:值得注意的是,堆棧分配無非是通過從堆棧指針寄存器中減去而無需任何複雜的邏輯(反對的malloc)固定棧頂更多,和靜態VS堆「速度」似乎是一個常見的誤解。