2016-04-15 7 views
0

次はchar x[2048]は、グローバルvarとfunc1ですがthread1によって呼び出され、単純なCのソースコード、ある、func2thread2によって呼び出される:IntelのCPUではchar型のX [2048]とキャッシュラインの問題

char x[2048]={0} , y[16]={0}; 

void func1(){ 
    strcpy(x,y); 
} 

void func2(){ 
    printf("(%s)\n",x); 
} 

int main(int argc, char **argv){ 
    strncpy(y,argv[1],sizeof(y)-1); 
} 

アル、

  1. thread1しばらく呼び出しfunc1する必要があります、1本のキャッシュラインは、xが32本の キャッシュラインを占有する必要がありますので、私の質問があり、その中に64バイトを持っていますその時までにそのCPUキャッシュに利用可能な32のキャッシュラインstrcpy? (または)コンパイラは、1つのキャッシュラインがジョブを実行するのに十分であることを知っていますか?

  2. thread2の間に、func2を呼び出すときまで、そのCPUキャッシュに使用できるキャッシュラインはすべてprintfですか? (または)コンパイラは、1つのキャッシュラインを識別することができますか?

+0

https://en.wikipedia.org/wiki/CPU_cache – user3386109

+2

コンパイラは通常、ハードウェアのキャッシュの内容を完全に認識していません。 – molbdnilo

+0

"strcpy/printf'を実行するとどういう意味ですか?キャッシュラインは何もしません。ただ存在するだけです。そして、「そのCPUに利用できる」とは何ですか? – Leeor

答えて

4

私はあなたがWikipediaのページを読むことをお勧め:https://en.wikipedia.org/wiki/CPU_cache

いくつかの背景:

  1. 通常、キャッシュライン($ L)は、プログラムに対して透過的です。だから、ほとんどのプログラマはキャッシュラインを扱っていない(それを持ってきて、それを蹴飛ばす)。 CPUは、一旦コード/データが$ Lにないことがわかると、そのようなメモリアクセスをストールし、オンデマンドで$ Lを持ち込むでしょう。
  2. コード内のデータをキャッシュラインに取り込むためのコーディング手法がありますが(たとえばプリフェッチ命令など)、通常はコンパイラがあまり早くプリフェッチする可能性があるため、これを行うには十分スマートではありませんそれが既に蹴られている)、または遅すぎる(CPUはまだメモリアクセスを停止しなければならない)。あなたへ

回答は、質問:

    号コンパイラが$ Lsが持ち込まれる必要があるどのように多くの知らない
  1. (どのようにそれは、データの一部が$ Lに既に存在するかどうかを知ることができ、それでちょうど安全な面であり、自分自身を圧倒してはいけません)。コンパイラはMOV命令などの命令を発行し、CPUはこの命令を実行している間にオペランドが$にないことを発見したので、オンデマンドでそれらを取り込みます。 '\ 0'までコピーのみをプログラムするので、$ Lはそこで停止します。
  2. #1と同じです。読み込まれた$ Lsだけが持ち込まれ、コンパイラはこれとは何の関係もありません。

詳細:現在必要とされるもののほかに、追加の$ Lsをもたらす可能性があるプリフェッチャ

  1. CPU。たとえば、データの局所性を考慮して次の$ Lを取り込む可能性があります。
  2. 一部の高度なプログラムは、プログラムのパフォーマンスを向上させるためにプリフェッチ命令を使用します。近い将来にあなたのコードがいくつかの場所にアクセスすることを知っていれば、それをプリフェッチすることができ、必要なときに$ Lのミスペナルティが発生することはありません。しかし、それを正しくするのは難しいです(コードのメモリアクセスパターンを知って、適切な場所にプリフェッチ命令を挿入する必要があります)。高性能コードの中にはソフトウェアパイプラインを設計するものもありますが、それは高度なトピックです。

https://en.wikipedia.org/wiki/Instruction_prefetch

0

x86およびx64(現代のARMおよび他の一般的なCPUと同様)では、キャッシュはユーザーモードプログラムに対して完全に透過的です。

結果として、strcpyが最初の読み取りを実行し、CPUが自動的に1つのキャッシュラインを引き込み、が\0で終了し、完了しました。 printf("%s",x)と同じこと。