9

出力速度をハードディスクの書き込み速度より高くするにはどうすればよいですか?

更新 1 : 以下を変更しました。

  1. ウイルス対策をオフにしました。変化なし。

  2. 新しい物理ディスクを挿入し、最初のパーティションをテストに使用しました。(最初のテスト用のディスクは、システム パーティションとは別の最後のパーティションにありましたが、同じ物理ディスク上にありました。) 結果: 同じ周期パターンがありますが、テスト中にシステムが応答しなくなることはありません。書き込み速度はいくらか速くなります (最初のパーティションを使用するか、システム パーティションとの干渉がなくなったためと考えられます)。暫定的な結論: システム パーティションから何らかの干渉がありました。

  3. 64 ビット Perl をインストールしました。サイクルはなくなり、すべてが 2 秒のタイムスケールで安定しています。シングル コアで 55% の CPU、書き込み速度は約 65 MB/秒です。

  4. 元のドライブで 64 ビット Perl を試しました。結果:その中間。8 秒のサイクル、CPU 20 ~ 50%、35 ~ 65 MB/秒 (0 ~ 100%、0 ~ 120 MB/秒のディープ サイクルの代わりに)。システムはわずかに反応しません。書き込み速度は50MB/秒。これは干渉理論を支持します。

  5. Perl スクリプトのフラッシュ。まだ試していません。


よし、最初のハードルを越えた。非常に大きなテキスト ファイル (20 GB など) を生成できる Perl スクリプトを作成しました。

print NUMBERS_OUTFILE $line;

$line は、末尾に「\n」が付いた長い文字列です。

Perl スクリプトが開始されると、書き込み速度は約 120 MB/秒 (スクリプト、 プロセス エクスプローラー、およびパフォーマンス モニターのプロセス Perl の「IO 書き込みバイト/秒」によって計算される値と一致します) であり、シングル コアで 100% の CPU です。それは実行されています。この速度は、ハードディスクの書き込み速度よりも速いと思います。

その後、しばらくすると (たとえば、20 秒で 2.7 GB が書き込まれると)、システム全体が非常に応答しなくなり、CPU が 0% に低下します。これは、たとえば 30 秒間続きます。これら 2 つのフェーズの平均書き込み速度は、ハードディスクの書き込み速度と一致しています。この段落に記載されている時間とサイズは、実行ごとに大きく異なります。これまでのところ、第 1 フェーズの 1 GB から 4.3 GB の範囲が観測されています。これは4.3 GB での実行のトランスクリプトです

テストで生成された 9.2 GB のテキスト ファイルには、これらのサイクルがいくつかあります。

ここに画像の説明を入力してください

何が起こっている?


完全なPerl スクリプトBAT ドライバー スクリプト(pre タグでフォーマットされた HTML)。2 つの環境変数 MBSIZE と OUTFILE が設定されている場合、Perl スクリプトは Windows 以外のプラットフォームでそのまま実行できるはずです。

プラットフォーム: ActiveState の Perl 5.10.0。(当初は 32 ビット、後に 64 ビット); ビルド 1004。Windows XP x64 SP2、ページ ファイルなし、8 GB RAM、AMD クアッド コア CPU、500 GB Green Caviar ハードディスク (書き込み速度 85 MB/s?)。

4

4 に答える 4

5

すべてのデータは、物理ディスクに効果的に置かれる前にバッファーにキャッシュされます。システムからのバッファ、ディスク自体内の別のバッファ (おそらく 32MB バッファ)。これらのバッファーをいっぱいにしている間、プログラムはフルスピードで 100% CPU で実行されます。バッファーがいっぱいになると、プログラムはディスクを待機するようになりますが、これはメモリやバッファーよりもはるかに遅く、この待機により、このすべての CPU の消費が停止します。

おそらく、コードを最初から「ディスクを待機」させることができます。これには、fflush().

于 2009-09-07T21:39:09.947 に答える
5

私は、バッファがいっぱいになってから空になることが問題だと言っている他のみんなと一緒です。バッファを持たないようにautoflushをオンにしてみてください(Perl の場合):

#!/usr/bin/perl

use strict;
use warnings;

use IO::Handle;

my $filename = "output.txt";

open my $numbers_outfile, ">", $filename
    or die "could not open $filename: $!";

$numbers_outfile->autoflush(1);

#each time through the loop should be 1 gig
for (1 .. 20) {
    #each time though the loop should be 1 meg
    for (1 .. 1024) {
        #print 1 meg of Zs
        print {$numbers_outfile} "Z" x (1024*1024)
    }
}

バッファは、少し印刷する場合、作業を行う場合、少し印刷する場合、何らかの作業を行う場合などに適しています。ただし、データをディスクに爆破するだけの場合は、奇妙な動作を引き起こす可能性があります。ファイルシステムが実行している書き込みキャッシュを無効にする必要がある場合もあります。

于 2009-09-08T01:43:12.597 に答える
4

おそらく、OS は可能な限り高速 (85 MB/秒) でディスクに書き込み、余分な 35 MB/秒をバッファーに入れ、それがいっぱいになると、アプリを一時停止してバッファーをフラッシュします。バッファーは 85 MB/s で排出されるため、排出には 35/85 = ~0.4 倍の時間がかかると予想されます。私が十分に目を細めれば、それはあなたのグラフと広く互換性があります。

バッファーのサイズは、一時停止時間とディスク速度の積として見積もることができます。

于 2009-09-07T21:44:14.787 に答える
3

グラフを見てください!緑色の線は、ディスク キューの長さの平均を示します。ある瞬間、ピークに達し、その後 CPU が 0 になります。IO Writes も 0 になります。2 番目のピークが表示されるまで、通常に戻ります。その後、CPU と IO の書き込みは通常に戻ります。その後、IO と CPU の両方が再び低下し、次のキュー ピークで再び上昇します。そしてまた下って、また上へ…

その時点でディスクが物理的な書き込みを行っている可能性があります。ただし、その時点でシステムがディスクの検証を行っており、書き込みを検証するために書き込んだばかりのデータを読み取って、データが正しく書き込まれていることを確認している可能性もあります。

もう 1 つ気になったのは、2.7 GB のサイズです。これを Windows システムで実行しているので、Windows が 32 ビット プロセスとして処理できるメモリ量とほぼ同じなので、少し疑わしくなります。64 ビットの Windows では、アプリケーションに最大 3 GB の RAM (少し少ない) が提供されますが、再度リリースする必要があります。Process Explorer を使用して、使用中の RAM の量と IO 読み取りの量を確認することをお勧めします。

そして、おそらく 64 ビットの Perl バージョンを使用します...

于 2009-09-07T22:43:07.550 に答える