我从以下回答中提出了这个问题: Efficiency of postincrement v.s. preincrement in C++
我找到了这个表达式:
a = b++ * 2;
他们说,上面b++
可以与乘法并行运行。
b++
如何与乘法并行运行?
我对该程序的理解是: 首先,我们将b的值复制到临时变量,然后递增b,最后将该值与该临时变量相乘2。 我们不是用b乘以那个临时变量,那么它将如何并行运行?
我从另一个答案Is there a performance difference between i++ and ++i in C++?
得到了关于临时变量的想法答案 0 :(得分:3)
你所说的是enter image description here。在这种情况下,处理器可以在b的副本上执行增量,同时也乘以旧的b。 这是处理器级别的非常细粒度的并行性,通常您可以期望它为您提供一些优势,具体取决于体系结构。
在预增量的情况下,相反,必须在处理器的流水线中等待增量操作的结果才能执行乘法,因此给你一个惩罚。 但是,这在语义上并不等同,因为a的值会有所不同。
答案 1 :(得分:3)
@ SimpleGuy的答案是一个非常合理的初步近似值。麻烦的是,它假定了简单理论模型(没有并行化)和现实世界之间的中间点。这个答案试图看一个更现实的模型,仍然没有假设一个特定的CPU。
要实现的主要是真正的CPU有寄存器和缓存。这些存在是因为内存操作比简单数学要昂贵得多。整数增量和整数位移的并行化(*2
在实际CPU上优化为<<1
是一个小问题;优化器主要考虑避免负载停滞。
因此,我们假设a
和b
不在CPU寄存器中。相关的内存操作是LOAD b
,STORE a
和STORE b
。一切都以LOAD b
开头,因此优化器可以尽可能地向上移动,甚至在可能的前一条指令之前(别名是这里的主要关注点)。只要STORE b
完成,b++
即可开始。 STORE a
可以在STORE b
之后发生,因此它被一条CPU指令(<<1
)延迟并不是一个大问题,并且通过并行化这两个操作几乎没有什么好处。 / p>
答案 2 :(得分:0)
b ++可以并行运行的原因如下
b++
是一个后增量,这意味着变量的值将在使用后递增。以下行可分为两部分
a = b++ * 2
第1部分:将b
与2
相乘
第2部分:b
增加1
的值
由于上面两个不依赖,因此可以并行运行。
如果是预增量,则意味着在使用前递增
a = ++b * 2
部分本来是
第1部分:按b
1
的值
第2部分:将b
与2
相乘(新)let a = {
如上所示,第二部分只能在执行第1部分后运行,因此存在依赖性和因此没有并行性。