我正在使用异步同时运行一个方法,但是当我检查我的CPU时,它显示8个中只有2个正在使用中。我的CPU利用率一直在13%-16%左右。 函数async应该在每次调用时创建一个新线程,因此应该能够使用更多的处理器,或者我是否理解错误?
这是我的代码:
for (map<string, Cell>::iterator a = cells.begin(); a != cells.end(); ++a)
{
for (map<string, Cell>::iterator b = cells.begin(); b != cells.end(); ++b)
{
if (a->first == b->first)
continue;
if (_paths.count("path_" + b->first + "_" + a->first) > 0)
{
continue;
}
tmp = "path_" + a->first + "_" + b->first;
auto future = async(launch::async, &Pathfinder::findPath, this, &a->second, &b->second, collisionZone);
_paths[tmp] = future.get();
}
}
我的概念错了吗?
编辑:
谢谢你们,我现在明白了。我不知道,在将来调用.get()会等待它完成,之后似乎只是合乎逻辑......
但是,我现在编辑了我的代码:
for (map<string, Cell>::iterator a = cells.begin(); a != cells.end(); ++a)
{
for (map<string, Cell>::iterator b = cells.begin(); b != cells.end(); ++b)
{
if (a->first == b->first)
continue;
if (_paths.count("path_" + b->first + "_" + a->first) > 0)
{
continue;
}
tmp = "path_" + a->first + "_" + b->first;
mapBuffer[tmp] = async(launch::async, &Pathfinder::findPath, this, &a->second, &b->second, collisionZone);
}
}
for (map<string, future<list<Point>>>::iterator i = mapBuffer.begin(); i != mapBuffer.end(); ++i)
{
_paths[i->first] = i->second.get();
}
有效。现在它正确生成线程并使用我所有的CPU功率。你救了我很多麻烦!再次感谢。
答案 0 :(得分:1)
std::async
异步运行指定的函数并立即返回。那就是它。
由编译器决定如何做到这一点。一些编译器为每个异步操作创建线程,一些编译器有线程池。
我建议您阅读:https://stackoverflow.com/a/15775870/2786682
顺便说一下,您的代码并没有真正使用std::async
,因为您在产生&#39;之后正在对future.get
进行同步通话。异步操作。
答案 1 :(得分:1)
是的,你确实弄错了。在编写任何代码之前,并行代码需要一些想法。
您的代码会创建一个future
(可能并且可能会生成一个新线程),然后立即强制新创建的future
停止(调用其.get()
方法),同步,并返回结果。
因此,使用此策略,您的代码在任何时间点都不会使用超过2个cpu内核。它不能。
实际上,大部分时间你的代码只使用一个核心!
诀窍是&#34;并行化&#34;你的代码。
答案 2 :(得分:0)
回答根本问题:
您可能应该通过拆分循环来重构代码。在第一个循环中,您创建所有期货并将它们放在由tmp
索引的地图中。在第二个循环中,您遍历此地图并获取每个未来的所有值,并将结果存储在_paths
在第一个循环之后,你将有很多期货并行运行,所以你的核心应该足够忙。如果cells
足够大(&gt; numCores),那么拆分内循环可能是明智的。