【发布时间】:2014-12-31 01:21:12
【问题描述】:
我觉得我在这里遗漏了一些东西......
我稍微修改了一些代码,从使用std::thread 更改为std::async,并注意到性能有了显着提高。我编写了一个简单的测试,我假设使用std::thread 运行它应该与使用std::async 运行几乎相同。
std::atomic<int> someCount = 0;
const int THREADS = 200;
std::vector<std::thread> threadVec(THREADS);
std::vector<std::future<void>> futureVec(THREADS);
auto lam = [&]()
{
for (int i = 0; i < 100; ++i)
someCount++;
};
for (int i = 0; i < THREADS; ++i)
threadVec[i] = std::thread(lam);
for (int i = 0; i < THREADS; ++i)
threadVec[i].join();
for (int i = 0; i < THREADS; ++i)
futureVec[i] = std::async(std::launch::async, lam);
for (int i = 0; i < THREADS; ++i)
futureVec[i].get();
我没有深入分析,但一些初步结果表明std::async 代码的运行速度似乎快了 10 倍!关闭优化后结果略有不同,我也尝试切换执行顺序。
这是一些 Visual Studio 编译器问题吗?还是有一些我忽略的更深层次的实现问题会导致这种性能差异?我认为std::async 是std::thread 调用的包装器?
还考虑到这些差异,我想知道在这里获得最佳性能的方法是什么? (创建线程的不止 std::thread 和 std::async )
如果我想要分离线程怎么办? (据我所知,std::async 无法做到这一点)
【问题讨论】:
-
如果你有多个 thread::hardware_concurrency() 线程,你就不再使用真正的并发,你的操作系统必须管理上下文切换的开销。顺便说一句,您是否尝试在线程循环中添加 yield() ?
-
是的,这个例子被夸大了——我这样做是为了看看这两个调用有多“等效”。我仍然注意到一次运行
-
在 lambda 函数的循环中。目标是简化上下文切换。它不会神奇地消除您的软件线程开销,但它可能会消除一些瓶颈效应。
标签: c++ multithreading c++11 asynchronous visual-studio-2013