
ファイルサポート共有メモリを使用すると、奇妙なパフォーマンス動作が見つかりました(たとえば、カスタムファイルを開いてプロセススペースにmmap()するなど)。共有メモリの一部をmemcpy()すると、ミリ秒の遅延が観察されることがあります。具体的には、通常2048バイトをコピーするのに0.4usかかりますが、同じ数のバイトをコピーするのに約10〜20ミリ秒かかることがあります。これはいつでもランダムに発生する可能性があります。次の 2048 フレームのデータは通常時間に戻ります。
カーネルバージョンは2.6.27.23-0.1-preemptです。
何が起こっているのか、遅れの原因に関する手がかりを提供してくれた皆さんに感謝します。私もshm_open()を使ってみたところ、mmap()を使ってみましたが、違いはありませんでした。
呼び出しはmmap
次のとおりです。
int fd = ::open("somefile", flags, 0666);
if(fd != -1) {
myBasePointer = ::mmap(0, sizeInBytes,
PROT_READ|PROT_WRITE, MAP_SHARED,
fd, offsetInBytes);
}
あるプロセスはファイルを作成してmmap
保存し、もう一方のプロセスはファイルを開き、mmap
そのアドレス空間に入れます。ファイルは、一般ファイルシステムの一般ファイルです。
答え1
アイデア1:ページが常に実際のRAMとしてサポートされるように、mmap呼び出しにMAP_LOCKEDを追加してみてください。 RAMが多い場合でも、何らかの理由で必要な部品がページアウトされる可能性があります。待機時間に敏感であるように見えるため、現在のハードウェアで使用可能なRAM容量に関係なく、このフラグを指定することをお勧めします。
アイデア2:ページテーブルエントリがエラー時間ではなくmmap時間に生成されるようにMAP_POPULATEも指定します。私が知っている限り、これは最初のページエラーでのみ遅延を引き起こし、その後のページエラーでは発生しません。しかし、それはもう一つの良い守備訓練でした。
アイデア3:実際のファイルとしてサポートされるのではなく、匿名共有マップを使用してファイルシステムを削除すると、遅延は消えますか?役に立つ場合は、常に匿名共有領域の内容をセカンダリスレッドのファイルに書き込むことができます(おそらく低い頻度で)。
アイデア4:最新のカーネルを試してください。あなたが質問した後、Linuxカーネルが大幅に変更されました。
最後に、memcpyの待ち時間をどのように測定しますか?あなたは次のことに該当しないと確信していますか?
- 現在の時間を把握するための大きな遅延も含まれますか?たとえば、システムコールを呼び出すと、システムコールが遅延または遅延します。
- NTP 修正によるクロックジャンプは含まれません。
- ロック待ち時間を含む(2kのmemcpyはアトミックではありません)
- 精度より精度の高い時間測定方法を使用していますか?