gpt4 book ai didi

c++ - 特征:访问 Matrix 4 列的速度慢

转载 作者:行者123 更新时间:2023-11-30 05:20:31 24 4
gpt4 key购买 nike

我将 Eigen 用于类似于 Cholesky 更新的操作,这意味着在固定大小的矩阵(通常是 Matrix4d)的列上有很多 AXPY(和加乘以标量)。简而言之,访问 Matrix 4 的列的成本是访问 Vector 4 的 3 倍。

通常是以下代码:

for(int i=0;i<4;++i )  L.col(0) += x*y[i];

比下面的代码效率低 3 倍:

for(int i=0;i<4;++i )  l4 += x*y[i];

其中 L 通常是大小为 4 的矩阵,x、y 和 l4 是大小为 4 的 vector 。

此外,第一行代码所花费的时间并不取决于矩阵存储组织(RowMajor 或 ColMajor)。

在 Intel i7 (2.5GHz) 上, vector 运算大约需要 0.007us,矩阵运算大约需要 0.02us(计时是通过重复相同的运算 100000 次来完成的)。我的应用程序将需要数千次这样的操作,时间可能远低于毫秒。

问题:在访问 4x4 矩阵的列时我做错了什么?有什么办法可以让第一行代码更有效率吗?

用于计时的完整代码如下:

#include <iostream>
#include <Eigen/Core>
#include <vector>
#include <sys/time.h>

typedef Eigen::Matrix<double,4,1,Eigen::ColMajor> Vector4;
//typedef Eigen::Matrix<double,4,4,Eigen::RowMajor,4,4> Matrix4;
typedef Eigen::Matrix<double,4,4,Eigen::ColMajor,4,4> Matrix4;

inline double operator- ( const struct timeval & t1,const struct timeval & t0)
{
/* TODO: double check the double conversion from long (on 64x). */
return double(t1.tv_sec - t0.tv_sec)+1e-6*double(t1.tv_usec - t0.tv_usec);
}

void sumCols( Matrix4 & L,
Vector4 & x4,
Vector4 & y)
{
for(int i=0;i<4;++i )
{
L.col(0) += x4*y[i];
}
}

void sumVec( Vector4 & L,
Vector4 & x4,
Vector4 & y)
{
for(int i=0;i<4;++i )
{
//L.tail(4-i) += x4.tail(4-i)*y[i];
L += x4 *y[i];
}
}

int main()
{
using namespace Eigen;

const int NBT = 1000000;

struct timeval t0,t1;

std::vector< Vector4> x4s(NBT);
std::vector< Vector4> y4s(NBT);
std::vector< Vector4> z4s(NBT);
std::vector< Matrix4> L4s(NBT);

for(int i=0;i<NBT;++i)
{
x4s[i] = Vector4::Random();
y4s[i] = Vector4::Random();
L4s[i] = Matrix4::Random();
}

int sample = int(z4s[55][2]/10*NBT);
std::cout << "*** SAMPLE = " << sample << std::endl;

gettimeofday(&t0,NULL);
for(int i=0;i<NBT;++i)
{
sumCols(L4s[i], x4s[i], y4s[i]);
}
gettimeofday(&t1,NULL);
std::cout << (t1-t0) << std::endl;
std::cout << "\t\t\t\t\t\t\tForce check" << L4s[sample](1,0) << std::endl;

gettimeofday(&t0,NULL);
for(int i=0;i<NBT;++i)
{
sumVec(z4s[i], x4s[i], y4s[i]);
}
gettimeofday(&t1,NULL);
std::cout << (t1-t0) << std::endl;
std::cout << "\t\t\t\t\t\t\tForce check" << z4s[sample][2] << std::endl;

return -1;
}

最佳答案

正如我在评论中所说,生成的程序集对于这两个函数是完全相同的。

问题是你的基准在 L4sz4s 大 4 倍的意义上是有偏差的,因此你在矩阵情况下比在矩阵情况下得到更多的缓存未命中 vector 案例。

关于c++ - 特征:访问 Matrix 4 列的速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40638292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com