具有空构造函数使数组未初始化会使计算速度变慢

Having empty constructor that leaves arrays uninitialized makes slower calculation

本文关键字:计算 速度 初始化 构造函数 数组      更新时间:2023-10-16

我对一件事感到非常困惑... 如果我将构造函数添加到结构 A,那么在 for 循环中计算会变慢很多倍。为什么?我不知道。

在我的计算机上,输出中代码段的时间是:

带构造函数:1351

不带构造函数:220

这是一个代码:

#include <iostream>
#include <chrono>
#include <cmath>
using namespace std;
using namespace std::chrono;
const int SIZE = 1024 * 1024 * 32;
using type = int;
struct A {
type a1[SIZE];
type a2[SIZE];
type a3[SIZE];
type a4[SIZE];
type a5[SIZE];
type a6[SIZE];
A() {} // comment this line and iteration will be twice faster
};
int main() {
A* a = new A();
int r;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for (int i = 0; i < SIZE; i++) {
r = sin(a->a1[i] * a->a2[i] * a->a3[i] * a->a4[i] * a->a5[i] * a->a6[i]);
}
high_resolution_clock::time_point t2 = high_resolution_clock::now();
cout << duration_cast<milliseconds>(t2 - t1).count() << ": " << r << endl;
delete a;
system("pause");
return 0;
}

但是,如果我像这样从 for 循环中删除 sin() 方法:

for (int i = 0; i < SIZE; i++) {
r = a->a1[i] * a->a2[i] * a->a3[i] * a->a4[i] * a->a5[i] * a->a6[i];
}

删除构造函数无关紧要,执行时间相同,等于 78。

你对这段代码有类似的行为吗?你知道其中的原因吗?

编辑: 我用Visual Studio 2013编译它

是的,如果在发布配置中编译(通过优化),则此行为在Visual Studio 2019中仍然可以重现。

如果struct A具有空的用户构造函数,则其字段在new A()后保持未初始化状态。

另一方面,如果struct A没有构造函数,则它将成为聚合,new A()用零填充其字段。

计算乘法然后正弦具有独立于输入参数的相同性能(如果它们不是非规范化值,这里不是这种情况),但是在初始化带有零的字段后,它们会出现在 CPU 缓存中,因此以下计算速度更快,这解释了无构造函数版本的"好处"(当然, 如果不包括在测量中,则包括对象构建的时间)。

如果保留空构造函数,然后手动用零填充对象:

A* a = new A();
for (int i = 0; i < SIZE; i++)
a->a1[i] = a->a2[i] = a->a3[i] = a->a4[i] = a->a5[i] = a->a6[i] = 0;

那么程序的速度将与A中没有构造函数的情况下一样快。