2017-04-19 7 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

コードレビューサイトはありません。 **コードレビューのFAQ **を読んでください。** iff **あなたのコードが正しいなら、それはその候補かもしれません。しかし、より多くの情報を明確に提供する必要があります。市場には非常に異なるCPUがたくさんあります。 – Olaf

+0

@Olaf will/proc/cpuinfo help?また、私はCPUの特定の答えを期待していないよ。このようなループのキャッシュパフォーマンスを改善する方法に関する一般的なガイドライン。 –

+0

ここでは十分ではありません。申し訳ありませんが、まだ広すぎます。ご理解ください。 – Olaf

答えて

1

掲載されたコードについては、 CPUはキャッシュラインを昇順に読み取り、キャッシュラインを昇順に書き込みます。それよりも良い(よりキャッシュフレンドリな)アクセスパターンはありません(CPUの「ハードウェアプリフェッチャ」によるものです)。

データのサイズを小さくすることができます(ただし、表示されません)。

キャッシュミス率に影響を与えないコード(clflush、SIMD)を改善する方法もあります。