2012-06-30 16 views
6

私は自分の記憶をフラッシュする必要があるCプログラムを書いています。私はCPUキャッシュをフラッシュするためのUNIXシステムコマンドがあるかどうか知りたいです。CプログラムからLinuxのCPUキャッシュをフラッシュするには?

これは自分のロジックに要する時間を計算することを含む、私のプロジェクトの要件です。

私はcacheflush(char *s, int a, int b)関数について読んだことがありますが、それが適切かどうか、パラメータに渡すものについてはわかりません。私はそれを取る

+3

なぜあなたは*キャッシュをフラッシュする*必要がありますか? –

+0

私のプロジェクトにはロジックの時間を計算する必要があるため、キャッシュをフラッシュする必要があります。 –

+0

可能な複製http://stackoverflow.com/questions/1756825/cpu-cache-flush – Tudor

答えて

6
  1. あなたは「CPUキャッシュ」、いないメモリキャッシュを意味

  2. 上記のリンクは良好である:提案は、「CPUを経由して大量のデータを書き込み」ない Windows固有である

  3. ここで同じテーマの別のバリエーションです:

  4. は、LinuxとCPUのキャッシュについての記事です:

注:この(非常に、非常に低い)レベルでは

、 "Linuxの" != "Unix"

+0

ありがとうございました。役に立った人達と本当に良いコミュニティです...私のCプログラムで小さなサンプルコードを使って 'echo 3>/proc/sys/vm/drop_caches'をどのように使うべきか説明してください。 –

+0

* nixの美しさの部分の1つ(一般的にはUnixとLinux)は、 "ファイルのようなものすべて"を扱うことができるということです。特に: 'fopen("/proc/sys/vm/drop_caches "、" w "); fprintf(fp、 "3"); fclose(fp); ' PS:*これが宿題の場合は、あなたの質問に「宿題」タグを使用してください。 – paulsm4

+0

私はfopen( "proc/sys/vm.drop_caches"、 "w")....を使用していますが、キャッシュが実際にクリアされたことをどのように確認するのですか? @ paulsm4親切で助けてくれてありがとう。今回も助けてくれることを願っています。 :) –

2

ユーザモード(カーネルモードではない)プログラムであり、シングルスレッドの場合は、最初にキャッシュをフラッシュする必要はありません。あなたのユーザモードプログラムはそれが存在することさえ忘れることができます。あなたのプログラムの実行をスピードアップするだけであり、OSはプロセッサのMMUを介してそれを管理します。

あり、私はそのことを考えることができる唯一のカップルの理由は、あなたが実際にあなたのユーザーモードアプリケーションからキャッシュをフラッシュすることがあります、次のとおりです。

  1. アプリが対称型マルチプロセッサシステム上で実行するためのもの、あるいは持ってい
  2. パフォーマンステストのためにキャッシュをテストするだけです(この場合、カーネルモードで動作するように、おそらくドライバーとしてテストを書くべきでしょう)。これは、あなたがあなただけに書いたメモリのブロックを持っていて、必ずそれがキャッシュからフラッシュだようにしたいと仮定し

    #include <asm/cachectl.h> 
    
    int cacheflush(char *addr, int nbytes, int cache); 
    

    Linuxを使っていると仮定すると、いずれの場合には

、...メインメモリに戻る。ブロックは、addrから始まり、それは長いNBYTESだし、それは2つのキャッシュ(またはその両方)のいずれかにあります:あなたはメモリー」にデータを書き込むとき以来

ICACHE Flush the instruction cache. 
    DCACHE Write back to memory and invalidate the affected valid cache lines. 
    BCACHE Same as (ICACHE|DCACHE). 

は、通常は、DCACHEをフラッシュするのみ必要があるだろう"(つまりキャッシュに)、それは通常データであり、命令ではありません。

いくつかの奇妙なテストの理由で「すべてのキャッシュ」をフラッシュしたい場合は、CPUのキャッシュよりも大きいことを知っている大きなブロックをmalloc()することができます。古いゴミを書き込んでブロック全体をフラッシュするだけです。

も参照してください:私の最初の答えについて申し訳ありませんHow to perform cache operations in C++?

+0

とても助けてくれてありがとう。 ubuntu/unix/linuxのCPUキャッシュのサイズを知る方法は?キャッシュ全体をフラッシュしたい場合は –

+0

を参照してください。http://superuser.com/questions/48505/how-to-find-virtual-memory -size-and-cache-size-of-a-linux-system私の考える第二の答えはおそらくあなたが探しているもののラインに沿っていると思う。パフォーマンステストのためにキャッシュをフラッシュするというあなたの目標は間違っていると思います。パフォーマンステストでは、キャッシュにロードされた後にコードのパフォーマンスをテストし、キャッシュに入れてから、タイマーを使用して10,000回テストし、時間を10,000。 – phonetagger

+0

'エラー:asm/cachectl.h:そのようなファイルやディレクトリはありません' linuxのgnu-gccコンパイラはこのエラーを投げます。任意のアイデアを解決する方法...それはヘッダファイルとしてcachectl.hを受け入れます。 –

1

OKを、。私は後であなたの質問の下にあなたのフォローアップのコメントを読んだので、私は今あなたがあなたのプログラムをテストするときにあなたのプログラム(またはその一部)をキャッシュから起動するためにインストラクションキャッシュをフラッシュしたいと思います。主メモリから命令キャッシュへの初期ロード時間。また、データとコードの両方が新しくなるように、コードがメインメモリに使用するデータをフラッシュする必要がありますか?

何よりも先に、メインメモリ自体もキャッシュの一種であり、ハードディスク(ディスク上のプログラム、またはディスク上のスワップ領域)がプログラムの最も遅く、最も遅い場所です指示が出てくる可能性があります。つまり、最初にルーチンを実行したときに、すでに実行されている他のコードの近くにあるためにディスクからメイン・メモリにまだロードされていない場合は、そのCPU命令を最初にロードする必要がありますディスクから。これはメインメモリからキャッシュにロードするよりも長い時間がかかります。その後、メインメモリにロードされると、キャッシュからCPUの命令フェッチャにロードするよりも、メインメモリからキャッシュにロードするのに長い時間がかかります。だから、コードのコールドスタート性能をテストしたいのであれば、コールドスタートが何を意味するのかをディスクから取り出すか、メインメモリから引き出すかを決める必要があります。私は、メインメモリから命令/データをスワップ空間に「フラッシュする」命令を知らないので、メインメモリにフラッシュすることはできる限り多くのことがわかっていますが、心に留めておいてください命令キャッシュをフラッシュしたとしても、テスト結果が最初の実行(ディスクから取り出される可能性があります)から後続の実行までの実行結果と異なる場合があります。

ここで、自分のコードがメインメモリにフラッシュされるように命令キャッシュをフラッシュする方法はありますか?

これを行う必要がある場合(私の意見では非常に奇妙なことです)、私はおそらく、長さ&の私の関数をメモリに近似的に配置することから始めます。私はLinuxを使っているので、コマンド "objdump -d {myprogram}> myprogram.dump.txt"を発行して、myprogram.dump.txtをエディタで開き、フラッシュする機能を探しますそれらの開始アドレスから16進計算機を使用してエンドアドレスを減算することによってどれくらい時間がかかるかを計算します。私はそれぞれのサイズを書き留めます。後で私のコードでcacheflush()呼び出しを追加し、 'addr'と 'nbytes'として見つけた長さ、ICACHEとしてフラッシュしたい各関数のアドレスを与えます。ちょうど安全のために私はおそらくちょっと&のサイズを約10%増やしただけです。ちょっとしたコードを修正して、nbytesを調整するのを忘れてしまった場合に備えてください。 cacheflush()を呼び出すと、フラッシュしたい各関数が呼び出されます。次に、データをフラッシュする必要がある場合、グローバル/静的データを使用している場合は、それらをフラッシュすることもできます(DCACHE)が、スタックまたはヒープデータの場合、フラッシュすることができるかどうか、現実的には何もありませんそれはキャッシュから外れています。それをやろうとすると、通常の実行で決して存在しないか、まれにしか存在しない状態を作り出すので、愚かさの練習になるでしょう。 ところで

#include <asm/cachectl.h> 

int cacheflush(char *addr, int nbytes, int cache); 

...where cache is one of: 
    ICACHE Flush the instruction cache. 
    DCACHE Write back to memory and invalidate the affected valid cache lines. 
    BCACHE Same as (ICACHE|DCACHE). 

...あなたは、Linuxを使っていると仮定すると、クラスのこの宿題はありますか?

+0

Q:これはカーネルモードでのみ適用できますが、正しいですか? – paulsm4

+0

@ paulsm4 - Linuxのmanページには何も言われていません。うーん。マニュアルページを読んで...(Linuxを使用していると仮定していますが、もしそうなら、コマンド "man cacheflush"を試しましたか?)... ...底の近くに、私のバージョンでは2つのことがありますバグ - 現在の実装では、addrとnbytesの引数を無視しているため、キャッシュ全体が常にフラッシュされます。さらに下へ... "注 - このシステムコールは、MIPSベースのシステムでのみ利用可能であり、移植可能なプログラムでは使用しないでください。 – phonetagger

+1

@ paulsm4エラー:asm/cachectl.h:linux上のgnu-gccコンパイラがこのエラーをスローするファイルやディレクトリはありません。任意のアイデアを解決する方法...それはヘッダファイルとしてcachectl.hを受け入れます。 –

1

これは、Intelがキャッシュをフラッシュ示唆する方法である:

mem_flush(const void *p, unsigned int allocation_size){ 
    const size_t cache_line = 64; 
    const char *cp = (const char *)p; 
    size_t i = 0; 

    if (p == NULL || allocation_size <= 0) 
      return; 

    for (i = 0; i < allocation_size; i += cache_line) { 
      asm volatile("clflush (%0)\n\t" 
         : 
         : "r"(&cp[i]) 
         : "memory"); 
    } 

    asm volatile("sfence\n\t" 
       : 
       : 
       : "memory"); 
} 
+0

あなたのソースは何ですか? – horro

関連する問題