为什么改变这些指令的顺序会显著影响性能
Why does changing the order of these instructions significantly affect performance?
在学校的作业中,我正在对一个非常大的数字数组执行一个密集运算。在对整个数组的单线程版本进行基准测试并将我的结果与我同学的结果进行比较时,我注意到一些奇怪的行为。
功能如下:
int compute (char a[], int start, int end) {
int sum = 0;
int min = a[start];
int max = a[start];
for (int i = start; i < end; i++) {
if (a[i] > max) max = a[i];
if (a[i] < min) min = a[i];
int cube = a[i] * a[i] * a[i];
sum += cube;
}
return sum;
}
但是我同学的程序一直运行得更快,通常快得多。他的代码是相同的,除了循环体中指令的顺序:
for (int i = start; i < end; i++) {
int cube = a[i] * a[i] * a[i];
sum += cube;
if (a[i] > max) max = a[i];
if (a[i] < min) min = a[i];
}
下面是将每个版本的运行时与大小为1,000,000,000的输入数组(用随机带符号字节初始化)进行比较的输出:
Min/max first:
sum = 5445493143089, min = -128, max = 127
Completed in 1.050268 sec
Product-sum first:
sum = 5445493143089, min = -128, max = 127
Completed in 1.010639 sec
我们检查了两个版本的生成程序集,注意到存在相同的指令,只是顺序不同。据我所知,这应该不会产生如此显著的影响,但我可能错了。(我们还注意到所使用的寄存器差异很大,但是这个I 特别是疑问应该会产生影响。)
我们在编译C (-std=c11
)和c++ (-std=c++11
)时都会遇到这种行为。
为什么这些行的顺序严重影响顺序程序的行为?我们还对该操作的并行版本进行了基准测试,相比之下,它的行为几乎没有变化。我把内存重新排序作为一个可能的罪魁祸首,但这似乎不是问题,因为并行版本实际上没有受到影响(而且分区中没有重叠)。
密集的背对背测试显示行为。Product-sum总是比min/max快,即使在交替和允许缓存的情况下也是如此。
如果我们将显式跳转放入代码中,您可以看到在末尾带有条件的代码在大多数情况下可以避免一次跳转。这与编译器实际生成的代码类似。
第一种形式,最小/最大优先:
int i = lo;
goto start;
loop:
i++;
start:
if (!(i < hi)) goto end;
if (!(a[i] > ret.max)) goto label1;
ret.max = a[i];
label1:
if (!(a[i] < ret.min)) goto label2;
ret.min = a[i];
label2:
long long square = a[i] * a[i];
ret.sum += square;
goto loop;
end:
Second form, min/max last:
int i = lo;
goto start;
loop:
i++;
start:
if (!(i < hi)) goto end;
long long square = a[i] * a[i];
ret.sum += square;
if (!(a[i] > ret.max)) goto label1;
ret.max = a[i];
label1:
if (!(a[i] < ret.min)) goto loop;
ret.min = a[i];
goto loop;
end:
这可以简单到处理器跳转预测与循环底部的条件跳转效果更好…
相关文章:
- 数组中的不同浮点值会影响性能 10 倍 - 为什么?
- 为 lambda 分配名称会影响性能吗?
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 隐式转换函数的返回对象时是否会影响性能?
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- 性能 - 链接 C 尖锐和C++如何影响性能
- C 指针向量如何影响性能
- 公开类的内部组件,以防止编写过多代码和影响性能
- .NET 4,C ,IF..Else和Switch()如何影响性能
- 变量会影响性能吗
- 更改自动分配内存的范围是否会影响性能
- 如何修复不影响性能的"runtime error"?
- 返回间接类型化对象是否会影响性能
- 调用恒定复杂度O(1)5行函数会显著影响性能,原因如下
- 使用Pimpl的高级变体时可能会影响性能
- 功能原型设计会影响性能吗
- 在C/ c++中包含未使用的头文件会影响性能吗?
- 我可以在不影响性能的情况下将此宏更改为内联函数吗
- Dispatch_async在下面的代码中影响性能
- c++中的操作符重载如何影响性能