受这些说法的鼓舞,我想看看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;
}
这里没有什么花里胡哨的东西,它将函数对象f
和它的参数打包到一个std::packaged_task
中,并在一个新的std::thread
上启动它,然后分离线程,并返回任务的std::future
。
下面是使用std::chrono::high_resolution_clock
测量执行时间的代码:
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;
}
在这里,someTask()
是一个简单的方法,我会稍微等待一下,模拟一些完成的工作:
void someTask()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
最终结果:
- 顺序执行:1263615
- 线程执行:47111
- std::sync:821441
- 我的异步:30784
有人能够解释这些结果吗?似乎std::async
比我天真的实现或者直接分离的std::thread
要慢得多。为什么?在这些结果之后,还有使用std::async
的理由吗?
(请注意,我还使用了clang++和g++来进行此基准测试,并且结果非常相似)
更新:
在阅读Dave S的回答后,我对我的小型基准测试进行了以下更新:
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
。请保留HTML标签。