GCC与std :: async(std :: launch :: async)的行为与Clang的行为

时间:2012-04-07 23:35:32

标签: c++ gcc c++11 clang policy

有没有人有相当新的std::async的经验?我们目前正在实现并行文件解析器,它读取文件块并将此块传递给异步函数。

使用Clang(v3.0)这种方式可以很好地使用默认的std::async策略(取决于实现)。在一台双核机器上,它最多可以激活4个线程,效果非常好。

但是对于GCC(v4.7),文件读取线程不会产生任何新线程,使程序最终完全顺序。

使用std::launch::async,两个版本几乎都在做同样的事情(应该是这种情况)。

有谁知道GCC的c ++ 11线程功能的当前状态?或者这可能是我们实施中的错误?

简短代码:

while (readNewChunk()) {
    Chunk &chunk = fileReader_.getChunk(); //reading the file
    ChunkLoader *chunkLoader = new ChunkLoader();
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader);
    dictCreationFutures_.push_back(std::move(ftr));
}

4 个答案:

答案 0 :(得分:17)

行为符合规范,即使它不是您想要的。如果您未指定启动策略,则将其视为async|deferred,这意味着由实现来决定启动策略。如果给出选择,GCC总是选择deferred

答案 1 :(得分:4)

EDIT2:我会解释一下。

std :: async承诺'未来';那就是:当你想要它时,它会在那里。它现在可以计算,可以在你要求的时候计算,我们只是承诺它会发生。

就像我下面的海报一样,海湾合作委员会默认延期(这意味着,当它被要求时,它将履行承诺,并且可能不会事先)。这种默认的原因是因为GCC还没有提供适当的C ++ 11线程支持。除了许多其他方面,它没有一个好的内部线程调度程序。这有点像黑客。不,更像是一堆黑客。事实上,如果你在GCC上用C ++ 11编写线程代码,那么当它们实现功能时,它就会正常工作;现在,它大部分都是正常的。我的意思是,你到底得到了结果,对吧?

如果你告诉它启动一个线程,它会,因为它太愚蠢(目前)意识到它可以而且应该自己(不像CLang,它目前有更好的内部线程调度程序)。

编辑:说真的?误导下来改变了!

这是我的参考! http://gcc.gnu.org/projects/cxx0x.html。请注意,“并发”下的几乎所有内容(包括“内存模型”)均标注为“否”。 GCC.GNU.org。他们是你知道的海湾合作委员会的权威。

从我的评论中略微编辑:

我真的建议使用Boost。当GCC准备就绪时,它不会成为适当的C ++ 11支持的大跃进。 C ++ 11中的新线程模型需要与GCC或MSVC不同的内存布局,并且它们尚未真正实现。

答案 2 :(得分:1)

所以我明白这是2年后的事情,但我无法帮助但感觉有必要回应@ std' OrgnlDave关于GCC与CLang的评论,注意至少目前,2015年1月,clang版本3.5和GCC版本4.9具有完全相同的行为。当没有提供启动策略时,该行为默认为不同,并且在调用future :: get时执行,并且仅当显式提供异步启动策略时,编译器才会导致在后台执行该函数。

答案 3 :(得分:1)

一个更新的答案:GCC 7.3.0和Clang 6.0都将在默认启动策略的单独线程上执行C:\工作。两者都将创建与std::async()个调用一样多的线程(已测试100个调用)。

我不知道GCC的这种行为何时更改。