3

ページの障害に関するドキュメントを作成していて、具体的な数値を使用できるようにしようとしているので、12 * 1024*1024バイトのデータを読み取る簡単なプログラムを作成しました。簡単:

int main()
{
  FILE*in = fopen("data.bin", "rb");
  int i;
  int total=0;
  for(i=0; i<1024*1024*12; i++)
    total += fgetc(in);
  printf("%d\n", total);
}

そうです、それはファイル全体を調べて読み取ります。問題は、このプロセス中に1536回起動するdtraceプローブが必要なことです(12M / 8k)。すべてのfbt:mach_kernel:vm_fault *:プローブとすべてのvminfo :::プローブを数えても、500に到達しないため、適切なプローブが見つからないことがわかります。

ページがディスクからフォールトインされたときに起動するdtraceプローブをどこで見つけることができるか知っている人はいますか?

アップデート:

stdio関数でインテリジェントなプリフェッチが行われていることが問題であるという偶然の機会に、私は次のことを試みました。

int main()
{
  int in = open("data.bin", O_RDONLY | O_NONBLOCK);
  int i;
  int total=0;
  char buf[128];
  for(i=0; i<1024*1024*12; i++)
  {
    read(in, buf, 1);
    total += buf[0];
  }
  printf("%d\n", total);
}

このバージョンの実行にははるかに長い時間がかかります(リアルタイムで42秒、そのうちの10秒はユーザーで、残りはシステム時間でした-ページフォールトだと思います)が、それでも予想される5分の1のフォールトが生成されます。

不思議なことに、時間の増加はループのオーバーヘッドとキャスト(charからint)によるものではありません。これらのアクションだけを実行するコードバージョンは.07秒かかります。

4

3 に答える 3

1

直接的な答えではありませんが、ディスク読み取りとページフォールトを同一視しているようです。それらは必ずしも同じではありません。コードでは、ファイルから小さなユーザーメモリチャンクにデータを読み込んでいるため、I/Oシステムはファイルを任意の方法とサイズでバッファ/VMキャッシュに読み込むことができます。私はここで間違っているかもしれません、私はダーウィンがこれをどのように行うのかわかりません。

より信頼性の高いテストはmmap(2)、ファイル全体をプロセスメモリに入れてから、各ページにタッチすることです。

于 2010-08-13T20:03:56.010 に答える
1

私は最近同じラットホールを降りていました。現在、DTraceスクリプトまたはテストプログラムを利用できませんが、次のアドバイスを提供します。

1.)AmitSinghによるOSX Internalsを手に入れ、仮想メモリのセクション8.3を読んでください(これにより、DTraceプローブを選択するための適切な参照フレームが表示されます)。

2.)Brendan Gregg /JimMauroによるSolarisのパフォーマンスとツールを手に入れましょう。仮想メモリのセクションを読み、vminfoプロバイダーを使用するDTraceスクリプトの例に細心の注意を払ってください。

3.)OS Xは間違いなくファイルシステムからページの大きなチャンクをプリフェッチしており、テストプログラムはこの最適化を正しく実行しています(順番に読んでいるため)。興味深いことに、これはSolarisには当てはまりません。プリフェッチを無効にするために、大きな配列にランダムにアクセスしてみてください。

于 2010-11-30T04:24:10.933 に答える
0

個別の操作としてタッチされているすべてのページでオペレーティングシステムに障害が発生するという仮定(したがって、Nページにタッチすると、DTraceプローブがN回起動するのがわかります)に欠陥があります。ほとんどのUN*Xは、ある種の先読みまたは事前障害を実行し、ページとまったく同じ数の呼び出しを取得する可能性はほとんどありません。これは、mmap()を直接使用する場合でも同様です。

先読みおよびページクラスタリングの実装としきい値がすべてで同じになる可能性は低いため、正確な比率はファイルシステムによっても異なる場合があります。

mmapを直接使用してから、madvise(MAD​​V_DONTNEED)などを適用したり、msync(MS_INVALIDATE)を使用して範囲全体をパージしたりすると、ページごとのフォールトポリシーを強制できます。

于 2010-11-18T16:47:30.060 に答える