c++ - 放宽执行顺序规则

标签 c++ c optimization

C和C++标准规定执行顺序必须严格遵循源指令顺序。编译器可以自由地以任何顺序评估指令中的子表达式,但不能对用分号或冒号分隔的指令重新排序。

例如指令中:

A = A + B * C + D * E;

编译器可能会选择在 B*C 之前执行 D*E,或者在最后添加 A。

如果现在将相同的计算分成不同的指令:

int t1 = B * C;
t1 += D * E;
A += t1;

在这种情况下,编译器无法在 B * C 之后计算 D * E。

通常,这种代码会稍微慢一些,因为编译器无法针对特定硬件优化 CPU 指令的顺序。

我想做的是相反的方式。例如,如果一个展开的循环的主体显示为:

A[0] = B[0] * C[0];
A[1] = B[1] * C[1];
A[2] = B[2] * C[2];
A[3] = B[3] * C[3];

有没有办法告诉编译器这四个指令可以按任何顺序计算,因为它们对单独的数据进行操作?即使是不可移植的技巧也是受欢迎的。

最佳答案

The C and C++ standards specify that the order of execution must strictly follow the source instructions order.

不完全是。他们说程序的可观察行为 - 即 I/O 操作和对 volatile 对象的访问 - 必须就好像那样发生。只要不改变程序的行为,编译器仍然可以自由地重新排序评估。只要您的赋值和乘法运算没有明显的副作用,您的代码就可以重新排序。

但是,当您使用指针或引用时,问题就更多了。一般来说,编译器无法判断ABC 指向不同的内存区域,因此它必须假设一个赋值到 A 可能会更改以后使用的 BC 值之一。因此它不能重新排序评估。在 C 中,您可以使用 restrict 告诉编译器它们不重叠,但标准 C++ 中不存在此类功能。 (如果它们是数组,这不是问题,在这种情况下,编译器知道它们不重叠。)

关于c++ - 放宽执行顺序规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9535243/

相关文章:

c++ - STL算法删除容器中的所有对象?

c++ - 适当破坏某些类(class)成员

php - 如何知道共享主机中哪些查询消耗的 CPU 最多?

actionscript-3 - 如何优化除以100?

c++ - Eigen middleCols() 惩罚

c++ - 将位插入字节

c++ - 奇怪的 C++ 访问私有(private)成员问题

c - PulseAudio API - 无麦克风信号

Linux 中的 C 编程 : not getting correct output for program that finds number of occurrences of substring in file

c - 使用 calloc 在 C 中创建位图