2D矢量优化
2D Vector Optimization
这只是一个紧凑的测试用例,但我有双打的向量,我想填充所有成对差异的方形矩阵(2D矢量)。当使用-O3优化进行编译时,这在我的计算机上大约需要1.96秒(仅从嵌套的双循环中计算)。
#include <vector>
using namespace std;
int main(){
vector<double> a;
vector<vector<double> > b;
unsigned int i, j;
unsigned int n;
double d;
n=10000; //In practice, this value is MUCH bigger
a.resize(n);
for (i=0; i< n; i++){
a[i]=static_cast<double>(i);
}
b.resize(n);
for (i=0; i< n; i++){
b[i].resize(n);
b[i][i]=0.0; //Zero diagonal
}
for (i=0; i< n; i++){
for (j=i+1; j< n; j++){
d=a[i]-a[j];
//Commenting out the next two lines makes the code significantly faster
b[i][j]=d;
b[j][i]=d;
}
}
return 0;
}
但是,当我评论两行:
b[i][j]=d;
b[j][i]=d;
该程序在大约0.000003秒内完成(仅从嵌套的双循环计算)!我真的没想到这两行是限制速率的步骤。我已经盯着这个代码了一段时间,但我没有想法。任何人都可以就我如何优化这件简单的代码提供任何建议,以便大大减少时间?
当您评论这两行时,嵌套循环中剩下的一切都是保持计算d
,然后丢弃结果。由于这不会对程序的行为产生任何影响,因此编译器只会优化嵌套循环。这就是程序几乎立即完成的原因。
实际上,我通过用g++ -O3
进行两次编译代码来确认这一点,一次仅在嵌套环中使用d=a[i]-a[j]
语句,然后完全删除了嵌套环。发射的代码是相同的。
尽管如此,您的代码目前比其所需的要慢,因为它缺少缓存。当您在这样的嵌套环中访问二维数组时,如果可能的话,您应该始终安排迭代通过内存连续。这意味着第二个索引应该是变化更快的索引。对b[j][i]
的访问违反了此规则并缺少缓存。因此,让我们重写。
之前:
for (i=0; i< n; i++){
for (j=i+1; j< n; j++){
d=a[i]-a[j];
b[i][j]=d;
b[j][i]=d;
}
}
计时:
real 0m1.026s
user 0m0.824s
sys 0m0.196s
之后:
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
b[i][j] = a[j] - a[i];
}
for (j = i+1; j < n; j++) {
b[i][j] = a[i] - a[j];
}
}
计时:
real 0m0.335s
user 0m0.164s
sys 0m0.164s
相关文章:
- 空基优化子对象的地址
- 2D数组来自文本输入,中间有空格
- 将值指定给向量(2D)的向量中的某个位置
- 如何使用用户输入在C++中正确填充2D数组
- 关闭||运算符优化
- 如何在C++中检查2D数组中负值的输入验证
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 在 2D 向量中使用第三个 [ ] 有什么意义?
- 返回值优化:显式移动还是隐式
- 人脸跟踪arduino代码的优化
- 四边形的 2D 旋转
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 打印第二列时的2d字符矢量打印空间
- 优化2D旋转
- 操纵2D阵列的可能优化
- 2D矢量优化
- c++2D TileMap渲染优化
- 迭代非线性最小二乘优化3d到2d投影
- 优化 2D 阵列C++