C ++ 17通过使用可选的ExecutionPolicy参数(作为第一个参数)升级了69个STL算法以支持并行性。例如
std::sort(std::execution::par, begin(v), end(v));
我怀疑C ++ 17标准故意没有提及如何来实现多线程算法,而是由图书馆作者决定什么是最好的(并允许他们更改他们的思想,后来)。尽管如此,我仍然希望在高层次上理解在并行STL算法的实现中正在考虑哪些问题。
我心中的一些问题包括(但不限于!):
我意识到这些并行算法的目的是保护程序员不必担心这些细节。但是,任何能让我对图书馆内部内容进行高级概念的信息都将受到赞赏。
答案 0 :(得分:5)
截至今天,大多数问题都无法通过标准来回答。但是,正如我所理解的那样,您的问题混合了两个概念:
C1。并行算法的约束
C2。执行算法
所有C ++ 17并行STL事物都是关于C1:它设置了在并行计算中指令和/或线程如何交错/转换的约束。另一方面,C2即将标准化,关键字为executor
(稍后将详细介绍)。
对于C1,有3个标准策略(std::execution::seq
,par
和par_unseq
)对应于任务和指令并行的每个组合。例如,当执行整数累加时,可以使用par_unseq
,因为顺序并不重要。但是,对于浮点运算,其中加法不是关联的,更合适的是seq
,至少可以获得确定性结果。简而言之:策略设置了对并行计算的约束,这些约束可能被智能编译器利用。
另一方面,一旦你有一个并行算法及其约束(并且可能在一些优化/转换之后),executor
将找到执行它的方法。有默认执行程序(例如CPU)或者您可以创建自己的执行程序,然后,可以设置有关线程数,工作负载,处理单元等的所有配置。
截至今天,C1属于标准,但不属于C2,因此如果您将C1与兼容的编译器一起使用,您将无法指定所需的执行配置文件和库实现将为您决定(可能通过延期)。
所以,要解决你的问题:
(关于你的前5个问题)根据定义,C ++ 17并行STL库没有定义任何计算,只是数据依赖,以便允许可能的数据流转换。所有这些问题都将由executor
回答(希望如此),您可以看到当前的提案here。它看起来像:
executor = get_executor();
sort( std::execution::par.on(executor), vec.begin(), vec.end());
即使你的一些问题已在该提案中定义,我也不自信在这里讨论它们......但我鼓励你阅读它并提出你自己的答案;)
(对于第6个)有许多库已经实现了类似的概念(C ++ executor
的灵感来自其中一些),AFAIK:hpx,Thrust或Boost.Compute。我不知道最后两个是如何实际实现的,但是对于hpx,他们使用轻量级线程,你可以配置执行配置文件。此外,C ++ 17上面代码的预期(尚未标准化)语法基本上与hpx中的(受到很大启发)相同。
参考文献:
答案 1 :(得分:2)
Pre-final C++17 draft没有说明" 如何实施多线程算法",这是真的。实施所有者自己决定如何做到这一点。例如。 Parallel STL使用TBB作为线程后端,OpenMP作为矢量化后端。我想要了解这个实现如何与您的机器匹配 - 您需要阅读特定于实现的文档