在理论上,C ++实现是否可以并行处理两个函数参数的评估?

给定以下函数调用:

f(g(), h()) 

因为函数参数的求值顺序是未指定的(就我所知,仍然是C ++ 11中的情况),理论上可以并行执行g()h()吗?

这种平行化只能在gh被认为是相当平凡的(在最明显的情况下,只访问他们身体本地的数据),以避免引入并发问题,但除此之外,我看不到什么禁止它。

那么,标准允许吗? 即使只通过as-if规则?

(在这个答案中 ,曼卡塞尔否认了这一点 ,但是他没有引用这个标准,而且我对[expr.call]也没有显示出任何明显的措词。

要求来自[intro.execution]/15

…当调用一个函数时…在执行被调用函数的主体之前或之后,调用函数中的每个评估(包括其他函数调用)都没有被特定的sorting,所谓的函数[脚注: 换句话说,函数执行不会相互交错。 ]。

所以g()的主体的任何执行都必须用h() (因为h()是调用函数中的一个expression式)的评估(即不重复g()进行不确定的sorting。

这里的关键是g()h()都是函数调用。

(当然,as-if规则意味着不可能完全排除这种可能性,但决不应该以某种可能影响程序可观察行为的方式发生,这种实现最多只会改变代码。)

只要你不知道,编译器做什么来评估这些函数完全取决于编译器。 显然,function的评估不能涉及任何访问共享的,可变的数据,因为这将引入数据竞赛。 基本的指导原则是“仿佛”规则和基本可观察的操作,即对volatile数据的访问,I / O操作,对primefaces数据的访问等。相关部分是1.9 [intro.execution]。

除非编译器确切地知道g()h()和他们所调用的任何东西。

这两个expression式是函数调用,可能有未知的副作用。 因此,将其并行化可能会导致数据竞争。 由于C ++标准不允许参数评估引起expression式的任何副作用的数据竞争,所以如果编译器知道没有这种数据竞争是可能的,则它们只能并行化它们。

这意味着通过遍历每个函数,看看它们究竟是做什么和/或调用什么,然后通过这些函数进行跟踪等。在一般情况下,这是不可行的。

简单的答案:当functionsorting时 ,即使不确定,两者之间也不可能出现竞争状态,如果它们是并行的,则不是这样。 即使是一对“平凡”的function也可以做到。

 void g() { *p = *p + 1; } void h() { *p = *p - 1; } 

如果p是由gh共享的名称,则以任意顺序连续调用gh将导致p指向的值不变。 如果它们是并行的,那么*p的读取和它的分配可以在两者之间任意交错:

  1. g读取*p并find值1。
  2. f读取*p并且find值1。
  3. g写2到*p
  4. f ,仍然使用前面读取的值1将0写入*p

因此,并行化时的行为是不同的。