私は厄介な大きなxmlとテキストドキュメントを処理しようとしています:〜40GB。Windows7でVisualStudio2012を使用しています。
「Xerces」を使用して、xmlからヘッダー/「フッタータグ」を取得します。
ファイルの領域をマップしたいのですが、たとえば60〜120MBです。
マップを(3 *プロセッサ/コア)等しい部分に分割します。各部分をバッファーとして設定し、バッファーを配列にロードします。
次に、新しいスレッドでステートメント中に(#processors / cores)を使用して、バッファー配列をかみ砕きながら、文字/行/xmlサイクルを同期的にカウントします。1つのバッファが完了すると、プロセスは次の「使用可能な」バッファにジャンプし、完了したバッファはメモリからドロップされます。最後に、合計結果をプロジェクトログに追加します。
その後、ログを参照し、ファイルを文字数/サイズ(または他のオプション)で最も近い行またはサイクルに分割し、ヘッダーと「フッタータグ」をすべての分割にドロップします。
これを行っているのは、複数のコンピューターを備えたネットワークを介して大量のデータをMySQLサーバーにインポートできるようにするためです。
私の質問は、新しいスレッドでバッファ配列とファイルマップを作成するにはどうすればよいですか?
使ってもいいですか :
CreateFileに勝つ
CreateFileMappingに勝つ
MapViewOfFileに勝つ
標準のifstream操作とcharバッファーを使用しますか、それとも他のものを選択する必要がありますか?
さらに明確にするために:私の考えでは、ハードドライブでファイルを1つの場所から一方向にメモリにストリーミングできれば、マシンの全処理能力を使用して、別々であるが等しいバッファをかみ砕くことができます。
〜フレーバー:それは、フェンスで囲まれたエリア内にとどまる必要があるX羊用の2本の腕だけを備えた3〜6個の大きなバケツを備えた1つの巨大なビンから食べ物をすくい取ろうとするシェパードのようなものです。しかし、それらはすべて光速で動きます。
いくつかのアイデアや指針がここで私を助けるかもしれません。どんな考えでも大歓迎です。ありがとう。
while(getline(my_file, myStr))
{
characterCount += myStr.length();
lineCount++;
if(my_file.eof()){
break;
}
}
これは、テストの実行時に唯一のコードでした。2時間30分以上 2GBのRAMを搭載したデュアルコア1.6Mhzラップトップで実行するプログラムの合計プロセッサの45〜50%。現在ロードされているRAMのほとんどは、Firefoxで開いている最大50個のタブから600 + MB、60MBのVisualStudioなどです。
重要:テスト中、ウィンドウとダイアログボックスのみであるコードを実行しているプログラムは、それ自体の動作中のプライベートRAMセットを300K ish程度までダンプしているように見え、テスト。確かに、whileステートメント用に別のスレッドを作成する必要があります。ただし、これは、ファイルのどれもがバッファに読み込まれなかったことを意味します。CPUは、ハードドライブからのわずかな労力に追いつくために、実行全体で苦労していました。
PSCPUのボトルネックのさらなる証拠。ファイル全体をワイヤレスネットワーク経由で別のコンピューターに転送するのに20分かかる場合があります。これには、読み取りプロセスと、他のコンピューターでの書き込みプロセスへのソケットキャッチが含まれます。
アップデート
私はこの愛らしい小さなものを使って、前回のテスト時間から約15〜20分に移動しました。これは、MatsPeterssonが言っていたことと一致しています。
while (my_file.read( &bufferOne[0], bufferOne.size() ))
{{
int cc = my_file.gcount();
for (int i = 0; i < cc; i++)
{
if (bufferOne[i] == '\n')
lineCount++;
characterCount++;
}
currentPercent = characterCount/onePercent;
SendMessage(GetDlgItem(hDlg, IDC_GENPROGRESS), PBM_SETPOS, currentPercent, 0);
}
確かに、これは単一のループであり、実際には前のテストよりもはるかに適切に動作しました。このテストは、Getlineを使用したこのテストの上に示されているタイトループよりも約800%高速でした。このループのバッファーを20MBに設定しました。私はこのコードを次の場所からジャックしました:SOF-最速の例
しかし...
リソースmonとタスクマネージャーでプロセスをポーリングしているときに、最初のコアが75〜90%の使用率で、2番目のコアが25〜50%(私が開いているいくつかのマイナーな背景のもののかなりの標準)であることを明確に示したことを指摘しておきます。 )、およびハードドライブで..それを待ちます... 50%。ディスク時間は100%急上昇しますが、25%と低くなります。これらはすべて、基本的に、バッファ処理を2つの異なるスレッド間で分割することが非常に有益である可能性があることを意味します。すべてのシステムリソースを使用しますが、それが私が望んでいることです。今日、プロトタイプが機能するようになったら更新します。
メジャーアップデート:たくさんの学習を経て、ようやくプロジェクトが終了しました。ファイルマップは必要ありません。ベクトル文字の束のみ。動的に実行されるファイルストリーム行と文字カウンターを正常に構築しました。良いニュースは、以前の10〜15分のマーカーから5.8 GBのファイルBOOYAで〜3〜4分になりました!〜