2017-04-19 40 views
0

嘿所以我有寫在c緩存性能我必須改進的函數。統計數據由cachegrind提供。但是我完全陷入困境,無法獲得超過10%的性能提升。我真的需要幫助。提高緩存命中率

下面是函數:

#define LARGER 50000 

typedef struct { 
    char c1; 
    double f1; 
    int n1; 
    char c2; 
    int n2; 
    double f2; 
} data; 

char* func() 
{ 
    data* B = (data*) calloc(LARGER, sizeof(data)); 
    if (!B) return 0; 

    double sum_f = 0.0; 
    double sum_n = 0; 
    char* sum_c = (char*) malloc((2 * LARGER + 1) * sizeof(char)); 

    sum_c[2 * LARGER] = '\0'; 

    int i; 
    for(i = 0; i < LARGER; i++) 
    { 
     sum_f += B[i].f1 + B[i].f2; 
     sum_n += B[i].n1 + B[i].n2; 
     sum_c[2 * i] = B[i].c1; 
     sum_c[2 * i + 1] = B[i].c2; 
    } 

    free(B); 
    return sum_c; 
} 

,我首先注意到的是,struct data的定義不是很緩存友好的,因爲它有一噸的填充。

於是,我改變根據allignment requiirements這個定義 -

typedef struct { 
    int n1; 
    int n2; 
    double f1; 
    double f2; 
    char c1; 
    char c2; 
} data_new; 

但是這給了我大約只有10緩存性能%的增幅。我對如何修改for循環以進一步改善空間局部性沒有任何想法。

任何人都可以指導我如何能夠編寫更好的緩存友好的循環。

P.S.作爲我對計算機體系結構書的自學研究的一部分,我正在做這些問題,而且我沒有教師尋求幫助。

+0

我們不是代碼評論網站。 **閱讀代碼評論的常見問題解答**,如果你的代碼是正確的,它可能是他們的候選人。但是你應該提供明確的更多信息,市場上有很多非常不同的CPU。 – Olaf

+0

@Olaf會/ proc/cpuinfo有幫助嗎?此外,我不期待CPU具體的答案。只是關於如何改進這種循環的緩存性能的一般準則。 –

+0

不在這裏,不夠。對不起,還是太寬泛了。敬請諒解。 – Olaf

回答

1

對於發佈的代碼; CPU將按升序讀取緩存行並按升序寫入緩存行。沒有比這更好的(更容易緩存)訪問模式(部分原因是CPU的「硬件預取器」)。

你可以做的唯一的其他事情是減少數據的大小(但我看不出如何)。

還有一些改進代碼的方法(clflush,SIMD),這對緩存未命中率沒有任何影響。