2016-10-18 3 views
1

8プロセッサ・マシン上でこのスクリプトを検討:私の非同期コールをCPUの数に応じてチャンクに分割する必要がありますか?

int parallel_function(int i){ 
    system(some_complex_and_long_call); 
    return i; 
} 

int main() { 
    // Parallel run 
    std::vector<std::future<int>> futures; 
    for(int i = 30; i > 0; i--) { 
     futures.push_back (std::async(std::launch::async, parallel_function, i)); 
    } 
    std::cout << "Stuff submitted" << std::endl; 
    for(auto &e : futures) { 
     std::cout << e.get() << std::endl; 
    } 
return 0; 
} 

これは、非同期で30回のシステムコールを起動しますが、私はわずか8つのプロセッサを有し、各システムコールは(iは必要がありますね)の100%を使用することができシングルプロセッサ。

一度に8つのコール(またはさらに7つのプロセッサをフリーにしておく)を実行するか、それは問題ではありません。より速く走るのはなぜですか?

もう1つの質問: void関数を非同期で呼び出すことはできますか、関数は何かを返す必要がありますか?

+2

おそらく。多分。多くのものに依存します。なぜそれを試してみてはどうですか?とにかく、インターネットがあなたに何を伝えても、それは確かな唯一の方法です。 – Useless

+0

@Useless確かに私は試してみることができます、問題は私のシステムコールが実行する月のようなものです(彼らは高価なシミュレーションです)ので、最初に尋ねるかもしれませんが、より良いかもしれません:) –

+0

@GáborErdősそれはあなたのために仕上げる必要はありませんすべてのCPUリソースを消費しているかどうかを確認します。 – xaxxon

答えて

2

実際はstd:asyncの実装に依存します。

実際にsome_complex_and_long_callがCPUバインドタスクの場合、スレッドの数を(論理的な)コアの数にするのは合理的です。

GCCは実際にはstd::asyncコールごとにスレッドを生成するので、GCCバージョンasyncをあまり使いたくないかもしれません。スレッドの作成、スケジューリングと破壊はコストがかかり、コンテキストスイッチはパフォーマンスを低下させます。この場合は、スレッドプールの実装(githubにはたくさんあります)があり、asyncの代わりにスレッドプールを使用することをお勧めします。あなたが好きなだけasyncを生み出す、これらのコンパイラを使用していて、実装があなたのためのスレッドの作成の世話をするのであればstd::asyncを呼び出すときにクランとVC++

どちらも、舞台裏でスレッドプールを使用しています。

もう1つの質問:非同期でvoid関数を呼び出すことはできますか? 関数は何かを返す必要がありますか?

はい、可能です。この場合std::asyncstd::future<void>を返します。

1

は一般では、物理コアあたり1つのスレッドはおそらく最高で、もしスレッドがCPUバウンドであり、原則としてでは、スレッドごとに一つのタスクは、タスクを管理するのではなく、実際の仕事をして過ごした時間を最小限に抑えます。

これは、タスク(async parallel_function呼び出し)がすべて完了するまでにほぼ同じ時間がかかることを前提としています。そうでない場合は、最初の終了コアをビジー状態に保つためにさらに多くの作業が必要です。

実行に1ヶ月かかる場合(これは質問に含めるべき関連情報です)、私は24回の回避可能な同期操作が大きな違いを生み出すのではないかと疑います。

スケジューラがそれより多くのコンテキスト切り替えを行う場合、実際にはすべてが遅くなる可能性がありますが、プラットフォームがわからない場合もあります。


すべてIFSとhandwaving上記を参照してください?彼らは次のように翻訳します:

t1; drおそらく。多分。多くのものに依存します。なぜそれを試してみてはどうですか?とにかく、インターネットがあなたに何を伝えても、それは確かな唯一の方法です。

関連する問題