c++ - 编译器可以优化不相关的命令以使用不同的内核执行吗?
问题描述
编译器可以在优化方面改变非相关命令的顺序。它还可以静默优化它们以在不同的内核中执行吗?
例如:
...
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 竞争相同的寄存器,这在抽象顺序模型中可能并不明显。
所有这一切都间接影响执行以使硬件架构受益,没有明确的指令或声明。
推荐阅读
- javascript - 为什么删除列表项 [Js DOM] 时 removeChild() 不起作用?
- python - 在“if”语句中声明变量会导致问题
- python - Discord.py 机器人命令问题
- cypress - 在 Saucedemo.com 中使用 Cypress 检查排序按钮
- python - 如何在熊猫时间序列中的不同时间范围内进行嵌套循环?
- android-studio - 什么是错误消息“GradleDependency”?
- tableau-api - 过滤视图而不使用表计算函数过滤数据不适用于运行总和
- ssl - Kafka 生成 ssl .sh 文件卡住
- html - 我正在尝试这个 JSP 程序,但我收到 HTML 500 错误(找不到页面)
- python - Python中使用分而治之的一维寻峰算法