11

誰かがかなり新しいの経験がありstd::asyncますか? 現在、ファイル チャンクを読み取り、このチャンクを非同期関数に渡す並列ファイル パーサーを実装しています。

std::asyncこの方法で Clang (v3.0) を使用すると、デフォルトのポリシー (実装に依存)で非常にうまく機能します。2 コアのマシンでは、最大 4 つのスレッドが起動され、非常にうまく機能します。

しかし、GCC (v4.7) では、ファイル読み取りスレッドは新しいスレッドを生成しないため、プログラムは最終的に完全にシーケンシャルになります。

を使用するstd::launch::asyncと、両方のバージョンでほとんど同じことが行われます (どうあるべきか)。

現在の GCC の c++11 スレッド機能の状態を知っている人はいますか? それとも、これは実装のエラーでしょうか?

ショートコード:

while (readNewChunk()) {
    Chunk &chunk = fileReader_.getChunk(); //reading the file
    ChunkLoader *chunkLoader = new ChunkLoader();
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader);
    dictCreationFutures_.push_back(std::move(ftr));
}
4

4 に答える 4

17

あなたが望むものではなくても、動作は仕様の範囲内です。起動ポリシーを指定しない場合は、 と見なされますasync|deferred。つまり、どれを決定するかは実装次第です。GCC はdeferred、選択肢があれば常に選択します。

于 2012-04-08T02:20:09.240 に答える
5

EDIT2:もう少し説明します。

std::async は「未来」を約束します。つまり、必要なときにそこにあるということです。それは今計算されるかもしれませんし、あなたが要求したときに計算されるかもしれません。私たちはそれが起こることを約束しています。

下のポスターが指摘しているように、GCC はデフォルトで deferred になっています (つまり、要求されたときにその約束を果たしますが、おそらく事前ではありません)。このデフォルトの理由は、GCC が適切な C++11 スレッドのサポートをまだ提供していないためです。とりわけ、優れた内部スレッドスケジューラがありません。ちょっとしたハックです。いいえ、ハックの束のようなものです。実際、GCC 上の C++11 でスレッド化されたコードを記述した場合、実際に機能を実装すると正しく機能するようになります。今のところ、ほとんど正常に動作しています。つまり、最後に結果が得られますよね?

スレッドを起動するように指示すると、スレッドが起動します。(現時点では) 愚かすぎて、単独で実行できること、また実行する必要があることに気付くことができないためです (現在、より優れた内部スレッド スケジューラを備えている CLang とは異なります)。

編集:真剣に?間違ったダウンモッディング!

私の参考書はこちら! http://gcc.gnu.org/projects/cxx0x.html . 「メモリモデル」を含む「同時実行」の下のほとんどすべてが NO として示されていることに注意してください。GCC.GNU.org。彼らはあなたが知っているGCCの権威です。

私のコメントから少し編集しました:

Boostの使用を強くお勧めします。GCC の準備が整うと、C++11 の適切なサポートに大きく飛躍することはありません。C++11 の新しいスレッド モデルは、GCC や MSVC が使用しているメモリ レイアウトとは異なるメモリ レイアウトを必要とし、実際にはまだあまり実装されていません。

于 2012-04-07T23:50:36.677 に答える