Linuxが定期的にmmapファイルをディスクに同期させるのを防ぎ、物理メモリが不足しているときにOSが書き換えることを許可する方法があるかどうか疑問に思います。
私は大容量画像を処理するアプリケーションを作成しています。大きすぎるため、スワップスペースが数倍必要になることがあります。これにより、スワップ領域が使い果たされると、予期しないOOM競合が発生する可能性があります。
スワップを使わずに大きなメモリオブジェクトを割り当てる簡単な方法は、mmap()を呼び出すことです。この呼び出しは使用が非常に簡単でうまく機能しますが、パフォーマンスに深刻な影響を与える1つの主な問題があります。オペレーティングシステムは定期的にmmap領域にダーティページを作成します。
私のアプリケーションでは、CPU使用率が約2900%から約700%に減少し、プロセス速度が4倍遅くなりました。
以前、RedHatはオペレーティングシステムパラメータvm.flush_mapped_pagesを0に設定してこの動作をオフにすることを許可していましたが、この設定はもう存在せず、予期しない動作が発生する可能性があります。通常のタスクを処理します。
FreeBSDでは、mmap呼び出しでNO_SYNCフラグを使用してこの動作をオフにできますが、Linuxでは使用できません。
エラーを処理してEINTRを削除するコードを使用してmmapバッファを生成する方法は次のとおりです。
size_t n = 1048576*(size_t)1024*16; // 16G
int fd = open("mem.bin", O_TRUNC | O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
ftruncate(fd, n);
void* data = mmap(nullptr, n, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HUGE_2MB, fd, 0);
close(fd);
unlink("mem.bin");
このメモリを効率的に使用する方法はありますか?
答え1
vm.dirty_writeback_centisecs
sysctlを0に設定して、カーネルのバックグラウンドダーティページリフレッシュスレッドを無効にできます。また、vm.dirty_ratio
必ずしも必要でない限り、プロセスが強制的にダーティライトストアを実行しないように増やす必要があります。バックグラウンドリフレッシュスレッドが無効になっている場合とvm.dirty_background_ratio
sysctlsは関係ありません。vm.dirty_background_bytes
vm.dirty_expire_centisecs
残念ながら、ページごとまたはVMAで書き込み保存の動作を調整することは不可能だと思います。 VM サブシステム全体に対してのみ調整できます。