連続回転 sync() 呼び出しはどのように高い IO 待機につながりますか?

連続回転 sync() 呼び出しはどのように高い IO 待機につながりますか?

私がライブラリ呼び出しで理解している限りsync()、プロセスはすべてのダーティバッファをディスクにフラッシュできます。

sync() システムが呼び出すサービス・ルーチン sys_sync() は、一連の補助関数を呼び出します。

wakeup_bdflush(0);
sync_inodes(0);
sync_supers( );
sync_filesystems(0);
sync_filesystems(1);
sync_inodes(1);

呼び出しを一度実行したら、それsync()以降はバッファに何もないはずです。

フラグをstress実行するときというツールを使用しています。-isync() で N ワーカースレッドを作成する

stress --i 1

このコマンドは通話を送信し続けるため、高いIOレイテンシを消費すると仮定しますsync()。を使って確認しますltrace

sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0
sync()                                                                                                               = 0

連続同期呼び出しが多くのIOを消費する理由を説明できる人はいますか?最初の同期呼び出しの後、バッファは空でなければならないとします。

ベストアンサー1

sync() はデータベースのコミットに似ていますが、ディスク用です。 (実際にトランザクションデータベースの場合、コミットには通常ACIDを検証するのに役立つsync()呼び出しが含まれています...これを防ぐためにできることはすべてあります。)オペレーティングシステムの一般的なパフォーマンス最適化チャネル取付けの代わりに作業に指示します。システム:「今すぐ!」回転と同様に、機械式ディスクの性能は物理学に依存します。ドライブは、実際に要求された操作を実行する場所にヘッドを配置するのに時間がかかります。継続的に(または時々)同期すると、バッファリングとスケジューリングを通じてこのタスクを最適化する多くの機会を迂回します。また、sync()を呼び出すときもそうすることに注意してください。保留中のすべてのファイルシステムの書き込み、個々のファイルやファイルシステムだけでなく、メタデータも含まれます。

ディスクに4つのセクタ(最も内側のトラック(w1)に1つ、最も外側のトラック(w2)に1つ、ディスクの中間トラック(w3)に1つ)を書き込むプログラムがある簡単なシナリオを見てみましょう。 ))、そして最後に最も内側の軌道(w4)に戻ります...

プログラムがw1に書き込んでからsync()を呼び出すと、システムはすぐにドライブに書き込むように指示し、それによってドライブは最も内側のトラックに移動してセクタを書きます。その後、w2が発生してからsync()が発生するため、ドライブはセクタを書き込むために外部トラックに移動する必要があります。次のw3が発生し、ドライブはディスクの中央に戻ってセクタを書き込む必要があります。最後にw4が発生し、ドライブは最も内側のトラックに戻り、セクタを書き込む必要があります。ドライブヘッドが動くときにCPUは何をしていますか?文字通り待っています。

sync() 呼び出しをすべて実行しなかった場合、OS はすべての書き込みをバッファリングし、すぐにプログラムに戻り(「はい、はい...最終的には完了します」)、これで w1- が得られます。 w4バッファ。オペレーティングシステムとドライブの両方が、ドライブが各セクタを独立してまたは順次書き込むように強制することなく、意味のある方法で要求をスケジュールできます。したがって、OSがw4が入った後に書き込みを実行することを決定すると、4つの書き込みがすべてドライブに送信され、ドライブはw1とw4(つまり、最も内側のトラック)が最初に実行され、次にw3が実行されることがわかりますできます。 done(中間軌道)と最後にw2(最も外側の軌道)です。したがって、4つの個別の照会(ミリ秒単位)ではなく、3つの照会のみを実行します。そして、照会あたりの線形距離が短く、sync()シナリオよりも高速です。この非効率性を数百倍以上乗じてみると、継続的に同期するのに待つのに時間がかかるのがわかります。フラッシュドライブには同様のスケジューリング効率(たとえば、同じブロックに複数回書き込みなど)がありますが、メカニカルドライブほど影響はありません。

おすすめ記事