私はを火災に使うべきだと言われました& std::launch::async
パラメータのタスクのタイプを忘れてしまいました。(それで、新しい実行スレッドでは魔法が好きです)。これらのステートメントに励まさ std :: asyncは単純な分離スレッドと比較して遅いのはなぜですか?
std::async
見てみたかった:
- 順次実行
- シンプル戸建
std::thread
- 私の単純な非同期 "実装"
マイ単純な非同期実装は次のようになります。
template <typename F, typename... Args>
auto myAsync(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
std::packaged_task<decltype(f(args...))()> task(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
auto future = task.get_future();
std::thread thread(std::move(task));
thread.detach();
return future;
}
ここ空想何も、その引数と一緒にstd::packaged task
にファンクタf
パック、デタッチされた新しいstd::thread
上でそれを起動し、タスクからstd::future
で返します。今
そしてstd::chrono::high_resolution_clock
とコード計測実行時間:
void someTask()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
最後に、私の結果:someTask()
が行われ、いくつかの仕事をシミュレートし、私は少し待っ簡単な方法を、ある
int main(void)
{
constexpr unsigned short TIMES = 1000;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TIMES; ++i)
{
someTask();
}
auto dur = std::chrono::high_resolution_clock::now() - start;
auto tstart = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TIMES; ++i)
{
std::thread t(someTask);
t.detach();
}
auto tdur = std::chrono::high_resolution_clock::now() - tstart;
std::future<void> f;
auto astart = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TIMES; ++i)
{
f = std::async(std::launch::async, someTask);
}
auto adur = std::chrono::high_resolution_clock::now() - astart;
auto mastart = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TIMES; ++i)
{
f = myAsync(someTask);
}
auto madur = std::chrono::high_resolution_clock::now() - mastart;
std::cout << "Simple: " << std::chrono::duration_cast<std::chrono::microseconds>(dur).count() <<
std::endl << "Threaded: " << std::chrono::duration_cast<std::chrono::microseconds>(tdur).count() <<
std::endl << "std::sync: " << std::chrono::duration_cast<std::chrono::microseconds>(adur).count() <<
std::endl << "My async: " << std::chrono::duration_cast<std::chrono::microseconds>(madur).count() << std::endl;
return EXIT_SUCCESS;
}
:
- 順次:1263615
- スレッド:47111
- のstd ::同期:821441
- マイ非同期:30784
は誰は、これらの結果を説明してもらえますか? std::aysnc
のように思われます。私の純粋な実装よりも遅い、または単純明快で単純ながデタッチstd::thread
sです。 なぜですか?これらの結果の後にstd::async
を使用する理由がありますか?次のように私は私の小さなベンチマークを更新デイブSの答えを読んだ後
:
は
UPDATE(私が打ち鳴らす++とg ++、あまりにも、その結果は非常に類似していたと、このベンチマークをしたことに注意してください)
std::future<void> f[TIMES];
auto astart = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TIMES; ++i)
{
f[i] = std::async(std::launch::async, someTask);
}
auto adur = std::chrono::high_resolution_clock::now() - astart;
したがって、std::future
はすべての実行で破棄されないため、結合されません。このコードを変更した後、std::async
は私の実装と同じ結果をもたらします&はstd::thread
をデタッチします。
これは問題ではないと確信していますが、私は情報の完全性を求める必要があります。デバッグ(最適化されていない)またはリリース(最適化)されたビルドを測定していますか?私は最適化されたビルドを想定しています。それ以外の測定は無意味ですが、私は尋ねなければなりません。 –
@JesperJuhl完全に有効な質問ですが、私は-O2で測定しています。 –