C ++中向量向量中索引的最有效排序

时间:2016-05-14 20:03:25

标签: c++ vector

这主要是一个C ++概念问题。如果我有一个我必须访问的特定矩阵(存储为矢量矢量),每个维度的大小都非常不同。我有很多步骤可以遍历较大的维度并在较小的维度上执行操作。我想从这个矩阵的访问时间和操作效率的角度来看,以下两个例子中的哪一个会更有效:

组织1:

A=vector<vector<float>>(1000,vector<float>(10,0.0)); 
sumAcrossSmallerDimension=vector<float>(1000,0.0);

for(int i=0;i<1000;i++)
     for(int j=0;j<10;j++)
        sumAcrossSmallerDimension[i]+=A[i][j];

组织2:

A=vector<vector<float>>(10,vector<float>(1000,0.0)); 
sumAcrossSmallerDimension=vector<float>(1000,0.0);
for(int i=0;i<1000;i++)
     for(int j=0;j<10;j++)
        sumAcrossSmallerDimension[i]+=A[j][i];

在第二个例子中,似乎每个集合A条目的加载速度更快,但是为了在j维度上求和,你将在每次迭代中跳入内存10次以找到相应的j条目。

在第一个例子中,似乎加载A会比较慢,但是较低维度中的所有条目都可以用来求和。

对此感到好奇,谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

我认为线性地址空间而不是向量向量将为您提供最佳的缓存局部性:

#include <memory>
#include <algorithm>
#include <utility>
#include <vector>
#include <numeric>

struct vv
{
  vv(std::size_t rows, std::size_t columns, double init)
    : _rows(rows), _columns(columns), _size(_rows * _columns)
    , _pdata(std::make_unique<double[]>(_size))
    {
      std::fill(_pdata.get(), _pdata.get() + _size, init);
    }

  const double* operator[](std::size_t i) const {
    return std::addressof(_pdata.get()[i * _columns]);
  }

  double rowSum(std::size_t i) const {
    auto p = (*this)[i];
    return std::accumulate(p, p + _columns, 0.0, std::plus<>());
  }

  std::size_t _rows, _columns, _size;
  std::unique_ptr<double[]> _pdata;
};

int main()
{
  vv v(1000, 10, 10.0);

  auto sumAcrossSmallerDimension = std::vector<double>(1000,0.0);
  for(std::size_t i = 0 ; i < 1000 ; ++i)
  {
    sumAcrossSmallerDimension[i] += v.rowSum(i);
  }

}