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つは、mallocページが最初に作成されたときにLinuxがディスクから空のページを読み取る必要がないため、ページフォールトが発生しないことです。コードのループ部分を2回実行するようにコードを変更しました。
- また、Linuxの先読みを無効にしました(echo "0" >> /proc/sys/vm/page-cluster経由)。
この2つの変更で、約2G / 4K = 524,288ページのフォールト(正確には524,304)が見られました。
答え2
すべてのページが最初にメモリに書き込まれるとページエラーが発生するのはなぜですか?これは仮想メモリサブシステムにとって最悪の結果です。したがって、最適化、キャッシュ、プリロード、アクセスパターンの検出などにより、この数が減ります。これを試してみると、どのオペレーティングシステムでも計算された256,000のページエラーを確実に提供できることに驚くでしょう。
答え3
最適化を有効にし、コンパイラを使用してコンパイルしました。ループを削除しました、不気味な将軍完全なプログラム:
int main() {
while(1);
}