ページの不在が予想どおりに表示されないのはなぜですか?

ページの不在が予想どおりに表示されないのはなぜですか?

Linuxのページエラーの動作を調べようとしています。メモリを1 GBに制限するlxcコンテナを作成しました(/etc/lxc/default.confに 'lxc.cgroup.memory.limit_in_bytes = 1G'を追加して)。その後、単純なコードを実行して2GBのデータにアクセスしました。

int main() {
  char* buf = malloc(1024*1024*1024);
  char* buf2 = malloc(1024*1024*1024);
  if (buf == 0 || buf2 == 0) {
    printf("Malloc failed!\n");
    return 0;
  }
  int i,j,k;
  for (i=0; i<1024; i++)
    for (j=0; j<1024; j++)
      for (k=0; k<1024; k++)
        buf[i*1024*1024 + j*1024 + k] = i+j+k;
  for (i=0; i<1024; i++)
    for (j=0; j<1024; j++)
      for (k=0; k<1024; k++)
        buf2[i*1024*1024 + j*1024 + k] = i+j+k;
  free(buf);
  free(buf2);
  while(1);
  return 0;
}

コードは -O0 でコンパイルされ、コンテナ内で実行されます。プログラムがwhile(1)に達すると、どのくらいのページエラーが発生したかを確認します。

ps -eo maj_flt,cmd | grep a.out

ここで、a.outはコンパイルされた実行可能ファイルです。時には200〜300ページのエラーが表示されたり、時には10〜20ページのエラーのみが表示されることもあります。メモリが1Gしかないので、少なくとも1G/4K = 256Kのページフォルトは常に発生すると思います。時々10〜20ページのエラーしか表示されないのはなぜですか?私のLinuxはデフォルトで4Kページを使用していることを確認しました。

私はLinuxに初めて触れました。どんな洞察力でもとても役に立ちます!ありがとうございます。

答え1

この問題を解決しました。

  1. 私のコードの主な問題の1つは、mallocページが最初に作成されたときにLinuxがディスクから空のページを読み取る必要がないため、ページフォールトが発生しないことです。コードのループ部分を2回実行するようにコードを変更しました。
  2. また、Linuxの先読みを無効にしました(echo "0" >> /proc/sys/vm/page-cluster経由)。

この2つの変更で、約2G / 4K = 524,288ページのフォールト(正確には524,304)が見られました。

答え2

すべてのページが最初にメモリに書き込まれるとページエラーが発生するのはなぜですか?これは仮想メモリサブシステムにとって最悪の結果です。したがって、最適化、キャッシュ、プリロード、アクセスパターンの検出などにより、この数が減ります。これを試してみると、どのオペレーティングシステムでも計算された256,000のページエラーを確実に提供できることに驚くでしょう。

答え3

最適化を有効にし、コンパイラを使用してコンパイルしました。ループを削除しました、不気味な将軍完全なプログラム:

int main() {
  while(1);
}

関連情報