2

メモリに完全にロードできず、ランダムにアクセスされる非常に大きなメモリマップトファイル(200GB以上)を扱っています。マップされたファイルはソリッドステートドライブアレイに保存されますが、同じ検索が以前に行われ、使用されたページがすでにメモリに読み込まれていない限り、必要なパーツに一度に1つずつアクセスするのは非常に遅いことがわかります。

mmapの変数を読み取るために複数のスレッドを同時に追加すると、速度が劇的に向上し、テストの向上の上限に達することができませんでしたが、スレッドが1000を超えると、openmpがリソース使用不可エラーをスローします。

また、madviseを試して、必要となる特定の部分(MADV_WILLNEED)をカーネルにアドバイスしようとしましたが、カーネルは、違いを生むのに十分な速さでアドバイスに基づいて動作していないようです。

実際に使用される直前に必要なデータの部分を同時にプリフェッチする方法を探しています。変数(または変数を含むマップされたファイルのメモリページサイズの部分)を読み取るためのリソースを最も消費しない方法は、読み取りをブロックせずに変数をメモリに強制することです。

ブロッキングを回避できない場合は、非常に多数の非常に軽量なスレッドを実行して読み取りを行う方法も機能します。

4

1 に答える 1

2

あなたはあなた自身の質問に答えたようです。スレッド化以外の唯一の解決策はmadvise、それぞれに対して実行できるアクセスの数をループすることです。次に、x個madvise(たとえば10,000)の後に戻って、メモリにアクセスします。ただし、O / Sは、madviseが呼び出された順序でI/Oが実行されることを保証するものではないことに注意してください。したがって、O / Sは最初のmadviseを処理してから、madvisesの最後、またはアドレスが最も低いものにジャンプする可能性があります。必要に応じてI/Oを大幅に高速化する方法はありません。

例:

for(i=0; i < accesses + 10000; ++i)
{
    madvise(access[i].addr, access[i].length, MADV_WILLNEED);
    if(i >= 10000)
    {
        // Access location access[i-10000].addr
    }
}

ただし、ランダムアクセスを使用している場合は、このファイルのメモリマッピングが本当に実行したいのかどうかを自問する必要があります。非同期I/Oの方が理にかなっているように思われます。

于 2012-10-08T20:48:13.973 に答える