【问题标题】:How to speed std::vector access time如何加快 std::vector 访问时间
【发布时间】:2015-07-23 22:47:23
【问题描述】:

如何提高 std::vector 时间? 嗨,我正在为多变量模糊 k 表示集群制作软件。 它通过 10 个变量处理大矩阵的 50.000 个观察值。 矩阵不需要长大或缩小或边界检查。 仅将大小调整为所需大小,加载项目,然后进行大量访问。

第一次使用:

`std::vector< std::vector<double> > matrix(NumClusters, std::vector<double>(NumObs,0.0));`

获取元素:double A=matrix[i][j];但是处理时间是20分钟。

然后制作:

std::vector<double> U(NumClusters *NumObs,0.0);   

获取元素:double A=U[i*NumObs+j];而且时间更好。

现在想提出一个问题: 哪个会更快获得访问权限:

迭代器+整数

std::vector<double>::const_iterator Uit = U.begin();
double A= *(Uit+index)

指针[int]

std::vector<double>::const_pointer Upt = U.data();
double A= Upt[index];

或者普通的索引访问[int]

双 A= U[索引];

问候

【问题讨论】:

  • matrix[i][j] 你的问题是数据的局部性。你为什么不测试其他两个选项?在您的示例中,我更喜欢索引,因为迭代器没有为您做任何事情并且 更难 阅读。
  • 所有编译器都应该将 operator[] 内联到对指针的直接访问中,因此您无法获得比这更快的任何东西。也许你的瓶颈在别的地方
  • 应该是一样的。编译器最终应该对索引或指针访问做同样的事情。
  • 分析你的代码,而不是做出毫无结果的假设
  • 分析您的代码。在通过迭代器或operator[] 进行调试构建访问时,由于某些编译器执行完整性检查,很可能会更慢,但在发布构建中,我希望所有方法的时间几乎相同。

标签: c++ stdvector


【解决方案1】:

您可以尝试的一件事是切换行和列。如果您有一个 10 × 50,000 的矩阵,并且将其逐行放置,那么对行的操作将比对列的操作更有效,因为它们具有更好的局部性。您可能还想考虑std::valarray,因为该容器应该优化矢量数据的某些数学运算。

如前所述,就效率而言,使用索引与指针应该无关紧要。索引可能更具可读性。

您可能想要做的一个非常 C++ 的事情(它不应该对效率产生任何影响,只是代码可读性)是将向量包装在一个容器中,使其表现得像一个 2D 矩阵,但在下面使用一个连续的 1D 向量。看看How can I use a std::valarray to store/manipulate a contiguous 2D array? 以获得灵感。

【讨论】:

    【解决方案2】:

    当您将二维矩阵存储为vector&lt;vector&lt;int&gt;&gt; 时,您必须依次取消引用两个指针才能访问元素(双重间接)。这就是为什么大多数库将矩阵存储为线性数组vector&lt;int&gt;,就像您现在所做的那样。在这种情况下,只使用了单次间接,而且所有数据都以更紧凑的布局存储在内存中。

    现在关于最快的访问。理想情况下,您提到的所有三种访问形式都同样快。然而,没有一个编译器是完美的,有些编译器可能有内联深度调用的问题(至少 MSVC 似乎很少有这样的问题)。这就是为什么如果你想确保最大速度,你应该避免在你的内部循环中使用任何 C++ 抽象。只使用指针和索引,这确实是最快的方法。但是请注意,与其他方法相比,很可能没有加速(也许生成的程序集绝对相等)。

    作为结论,这种方式对我来说是最快的:

    auto ptr = matrix.data();
    auto num = matrix.size();
    for (size_t i = 0; i < num; i++)
        ptr[i] = ...; //do whatever complex math you have
    

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2017-08-22
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多