-1

このループを openMPed にするのにかなりの時間を費やしましたが、2 つのスレッドの場合、Wall 時間は 2 倍になります! 私は何か重要なものを見逃していますか?

全体的なタスクは、大きなファイル (~ 1GB) を並行して読み取ることです。ifstream はいくつかの文字列バッファに分割され、これらはデータを構造体 Symbol に挿入するために使用されます。ここまではすべて高速です。また、ループのプライベート変数 str と locVec を操作対象として指定しても、何も変わりません。

vector<string> strbuf; // filled from ifstream
vector< vector <Symbol> > symVec; // to be filled


#pragma omp parallel for num_threads(2) default(none) shared(strbuf, symVec)
for (int i=0; i<2; i++)
{
    string str = strbuf[i];
    std::stringstream ss(str);
    // no problem until here

    // this is where it slows down:
    vector<Symbol> locVec;
    std::copy(std::istream_iterator<Symbol>(ss), std::istream_iterator<Symbol>(), std::back_inserter(locVec));


    symVec[i] = locVec;
}

編集::不正確で申し訳ありませんが、ファイルの内容はすでに順次読み込まれており、この時点で strbufs に分割されています。ファイルは閉じられています。ループ内ではファイル アクセスはありません。

4

1 に答える 1

1

ファイルの異なるセクションで I/O を実行するよりも、ファイルに対してシーケンシャル I/O を実行する方がはるかに優れています。これは本質的に、基盤となるデバイスで多くのシークを引き起こすことになります (ここではディスクを想定しています)。これにより、ファイルを上記のバッファに読み込むために必要な、基礎となるシステム コールの量も増加します。1 つのスレッドを使用してファイル全体を順次 (おそらくmmap()を使用してMAP_POPULATE) 読み取り、処理を異なるスレッドに割り当てる方がよいでしょう。

aio_read()別のオプションは、何らかの理由でファイルを一度にすべて読み取りたくない場合に、さまざまなセクションで読み取りを処理するなどの呼び出しを使用することです。

すべてのコードがないと完全にはわかりませんが、単にファイルを開くだけではコンテンツがメモリ内にあるとは限らず、ファイルから読み取るとページ フォールトが発生し、実際のファイルの内容が読み取られることを覚えておいてください。読み取り/書き込みを使用してファイルから明示的に読み取ろうとしない場合、OSがそれを処理します。

于 2013-05-30T22:43:58.183 に答える