编译器可以根据优化更改不相关命令的顺序。是否还可以静默优化它们以在不同的内核中执行?
例如:
...
for (...)
{
//...
int a = a1+a2;
int b = b1+b2;
int c = c1+c2;
int d = d1+d2;
//...
}
...
在优化方面,是否可能不仅会改变执行顺序,还会改变内核数量?编译器在标准方面有任何限制吗?
UPD:我不是在问如何并行化代码,而是在问是否未显式并行化,它是否仍可以由编译器并行化?
在这里,不仅有眼神。这些指令(在您的示例中)很可能最终会并行运行,但这不是您的想法。
CPU中有许多级别的硬件并行性,多核只是最高的一个(1)。在CPU内核内部,您具有其他级别的硬件并行化,大多数情况下都是透明的2)(您不通过软件对其进行控制,并且实际上看不到它们,有时可能只是它们的副作用)。其中包括管道,额外的总线通道,每个核心有多个ALU(算术逻辑单元)和FPU(浮点单元)。
指令的不同阶段将在管道中并行运行(现代x86处理器有十几个管道阶段),并且可能不同的指令将在不同的ALUS中并行运行(现代x86 CPU每个内核约有5个ALU)。
这一切都发生在编译器不做任何事情的情况下2)。而且它是免费的(考虑到硬件,并非免费在硬件中添加此功能)。在不同内核中执行指令不是免费的。创建不同的线程成本很高。将数据移动到其他内核可用是昂贵的。等待其他内核执行的同步开销很大。创建和同步线程有很多开销。对于像这样的小指令,这是不值得的。从多线程中真正受益的情况将涉及到一种分析,该分析如今过于复杂,因此实际上不可行。将来有一天,编译器将能够识别您的串行算法实际上是一种排序算法,并且可以高效,正确地对其进行并行化。在那之前,我们必须依靠语言支持,
1)好,实际上是超线程。
2)正如MSalters指出的:
现代编译器非常了解各种ALU,并将尽力从中受益。特别是,寄存器分配得到了优化,因此您不必让ALU争夺同一个寄存器,这在抽象顺序模型中可能并不明显。
所有这一切都间接影响了执行,从而使硬件体系结构受益,没有明确的指令或声明。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句