web-dev-qa-db-ja.com

LinuxでディスクI / Oキャッシュをパージする方法は?

より予測可能なベンチマークのためにそれを行う必要があります。

50
taw

sync コマンド、または sync() 関数が必要なようです。

ディスクキャッシュのフラッシュが必要な場合:echo 3 | Sudo tee /proc/sys/vm/drop_caches

55
Chris Dennett

次のようにできます:

# sync # (move data, modified through FS -> HDD cache) + flush HDD cache
# echo 3 > /proc/sys/vm/drop_caches # (slab + pagecache) -> HDD (https://www.kernel.org/doc/Documentation/sysctl/vm.txt)
# blockdev --flushbufs /dev/sda
# hdparm -F /dev/sda

# NEXT COMMAND IS NOT FOR BENCHMARKING:
# should be run before unplug, flushes everything possible guaranteed.
# echo 1 > /sys/block/sdX/device/delete

Straceを使用して、これらが3つの異なるシステムコールであることを確認できます

また、hdparmを使用してHDDキャッシュをオフにすることが望ましい場合がありますが、ベンチマークの対象は不明です。

いずれにしても、HDDが最近使用したデータの最後の64/32/16 MBをキャッシュするのを防ぐことはできません。そのキャッシュを削除するには、いくつかのゼロを書き込み(およびフラッシュ)、HDDから無関係な場所を読み取ります。キャッシュは読み取り部分と書き込み部分に分割される可能性があるため、これが必要です。その後、HDDのベンチマークを行うことができます。

35
socketpair

ディスクキャッシュのパージ:echo 3 | Sudo tee /proc/sys/vm/drop_caches

コマンドのドキュメント: https://www.kernel.org/doc/Documentation/sysctl/vm.txt

これに書き込むと、カーネルはメモリからクリーンなキャッシュ、デントリ、およびiノードをドロップし、そのメモリを解放します。

ページキャッシュを解放するには:

echo 1 > /proc/sys/vm/drop_caches

デントリとiノードを解放するには:

echo 2 > /proc/sys/vm/drop_caches

ページキャッシュ、デントリ、およびiノードを解放するには:

echo 3 > /proc/sys/vm/drop_caches

これは非破壊的な操作であり、ダーティオブジェクトは解放できないため、キャッシュされたすべてのオブジェクトを解放するために、ユーザーは最初に「同期」を実行する必要があります。

21

十分に短い答え:(コピーペーストフレンドリー)

DISK=/dev/sdX # <===ADJUST THIS===
sync
echo 3 > /proc/sys/vm/drop_caches
blockdev --flushbufs $DISK
hdparm -F $DISK

説明:

sync:マニュアルページから:ファイルシステムバッファをフラッシュします。変更されたブロックをディスクに強制し、スーパーブロックを更新します。

echo 3 > /proc/sys/vm/drop_cacheカーネルドキュメントからこれにより、カーネルはクリーンキャッシュをドロップします

blockdev --flushbufs /dev/sda:マニュアルページから:ブロックデバイスioctlを呼び出して[バッファをフラッシュする]

hdparm -F /dev/sda:manページから:ドライブ上の書き込みキャッシュバッファーをフラッシュします(古いドライブはこれを実装しない場合があります)

Blockdevコマンドとhdparmコマンドは 上記の回答 に応じて似ていますが、デバイスに対して異なるioctlを発行します。

おそらくより良い方法:

(ディスクをフォーマットしたと仮定しますが、ディスクに直接書き込みたい場合は、これらのコマンドを調整できます)

これを最初のベンチマークの前に1回だけ実行します。

MOUNT=/mnt/test # <===ADJUST THIS===
# create a file with psuedo-random data. We will read it
# to fill the read cache of the HDD with garbage
dd if=/dev/urandom of=$MOUNT/temp-hddread.tmp bs=64M count=16

キャッシュを空にするたびにこれを実行します:

DISK=/dev/sdX # <===ADJUST THIS===
MOUNT=/mnt/test # <===AND THIS===
# create a file with psuedo-random data to fill the write cache
# of the disk with garbage. Delete it afterwards it's not useful anymore
dd if=/dev/urandom of=$MOUNT/temp-hddwrite.tmp bs=64M count=16
rm $MOUNT/temp-hddwrite.tmp
# see short good enough answer above
sync
echo 3 > /proc/sys/vm/drop_caches
blockdev --flushbufs $DISK
hdparm -F $DISK
# read the file with pseudo-random data to fill any read-cache
# the disk may have with garbage
dd if=$MOUNT/temp-hddread.tmp of=/dev/null

完了したらこれを実行します。

MOUNT=/mnt/test # <===ADJUST THIS===
# delete the temporary file with pseudo-random data
rm $MOUNT/temp-hddread.tmp

説明:

ディスクにはおそらくH/Wキャッシュがあります。 blockdevおよびhdparmコマンドを発行すると、設計上またはバグが原因で一部のディスクがキャッシュをクリアしない場合があります。これを補うために、これらのキャッシュにfillホッピングする擬似ランダムデータを書き込んで読み取り、キャッシュされたデータをキャッシュから削除します。キャッシュを満たすために必要なデータの量は、そのサイズによって異なります。上記のコマンドでは、ddを使用して16 * 64MB = 1024MBの読み取り/書き込みを行い、HDDのキャッシュが大きい場合は引数を調整します(データシートと実験は友達であり、実際のサイズを超える値を指定しても問題ありません)キャッシュの)。/dev/urandomをランダムデータのソースとして使用しているのは、高速であり、trueランダム性を気にしないためです(ディスクファームウェア可能性があるデータをキャッシュに保存する前に圧縮を使用する)。私は最初から/mnt/test/temp-hddread.tmpを作成しており、十分なランダムデータを読み取るたびに使用しています。十分なランダムデータを書き込むたびに、/ mnt/test/temp-hddwrite.tmpを作成および削除しています。

クレジット

この回答は、既存の回答の最良の部分に基づいて作成しました。

8
ndemou

テスト中のディスクをアンマウントおよび再マウントすると、すべてのキャッシュとバッファがリセットされます。

2
Phil