特征:访问矩阵4列的速度很慢
Eigen: Slow access to columns of Matrix 4
我使用Eigen进行类似于Cholesky更新的操作,这意味着在固定大小的矩阵(通常是Matrix4d)的列上有大量的AXPY(和加上标量乘法)。简而言之,访问矩阵4的列的开销是访问向量4的3倍。
通常,下面的代码:
for(int i=0;i<4;++i ) L.col(0) += x*y[i];
的效率是下面代码的三分之一:
for(int i=0;i<4;++i ) l4 += x*y[i];
其中L通常是大小为4的矩阵,x, y和14是大小为4的向量。
此外,在第一行代码中花费的时间并不取决于矩阵存储组织(RowMajor或ColMajor)。
在Intel i7 (2.5GHz)上,矢量运算大约需要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 << "tttttttForce 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 << "tttttttForce check" << z4s[sample][2] << std::endl;
return -1;
}
正如我在注释中所说,两个函数生成的程序集完全相同。
问题在于您的基准测试在L4s
比z4s
大4倍的意义上是有偏差的,因此在矩阵情况下比在向量情况下获得更多的缓存丢失。
相关文章:
- 具有N列和N行的矩阵,列必须具有N-1、N-2等值
- 为什么在读取文件大小时文件IO速度会发生变化
- 如何从棋盘上的箱号中找到行和列
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 在Linux和C++中的Windows上,散列字符串值会产生不同的输出
- 打印第二列时的2d字符矢量打印空间
- 使用QTreeView,如何通过调用函数只突出显示特定的行/列
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 查找矩阵C++中每一列和每一行的最小和最大元素
- C++ 乔列斯基因式分解
- 如何删除给定矩阵中的特定行和列以进行C++?
- 对对应于矩阵的行和列的对向量进行排序
- 如何在C++中获取二维数组中最少的一列数?
- 如何在 c++ 中仅循环访问特定列?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 是否可以在 QAbstractItemModel 中返回正数行数和零列数?
- 使用 GDAL 获取矢量数组中的所有行数和列数
- 特征:访问矩阵4列的速度很慢