gpt4 book ai didi

c++ - 使用 vector 在 C++ 中声明 3D 数组结构

转载 作者:太空宇宙 更新时间:2023-11-04 15:30:27 25 4
gpt4 key购买 nike

您好,我是一名使用 C++ 学习科学计算的研究生。我们的一些研究侧重于算法的速度,因此构建足够快的数组结构很重要。

我见过两种构造 3D 阵列的方法。第一个是使用 vector 库。

vector<vector<vector<double>>> a (isize,vector<double>(jsize,vector<double>(ksize,0)))

这给出了大小为 isize x jsize x ksize 的 3D 数组结构。

另一种是使用

构造一个包含大小为 isize* jsize * ksize 的一维数组的结构

新双[isize*jsize*ksize]。为了方便地访问 (i,j,k) 的特定位置,运算符重载是必要的(我说的对吗?)。

根据我的经验,第一个要快得多,因为它可以轻松访问位置 (i,j,k),而后一个必须计算位置并返回值。但是我看到有些人更喜欢后一种而不是第一种。为什么他们更喜欢后一种设置?使用第一个有什么缺点吗?

提前致谢。

最佳答案

它们之间的主要区别在于布局:

vector<vector<vector<T>>>

这将为您提供一维数组 vector<vector<T>> .
每个项目都是一个一维数组 vector<T> .
这些一维数组中的每一项都是 T 的一维数组。

重点是,vector本身不存储其内容。它管理一 block 内存,并将内容存储在那里。这会带来许多不良后果:

  1. 对于维度为 X·Y·Z 的矩阵,您最终将分配 1 + X + X·Y。内存块。这非常慢,并且会破坏堆。想象一下:一个大小为 20 的立方体矩阵会触发 421 次对 new 的调用。 !
  2. 要访问单元格,您有 3 个间接级别:
    • 您必须访问 vector<vector<vector<T>>>对象获取指向顶级内存块的指针。
    • 然后您必须访问 vector<vector<T>>对象获取指向二级内存块的指针。
    • 然后您必须访问 vector<T>对象以获取指向叶内存块的指针。
    • 只有这样您才能访问 T数据。
  3. 这些内存块将散布在堆中,导致大量缓存未命中并减慢整体计算速度。
  4. 如果您在某个时候弄错了,您的矩阵中的某些行可能会具有不同的长度。毕竟,它们是独立的一维数组。

另一方面,拥有一个连续的内存块(如 new T[X * Y * Z] )会给出:

  1. 你分配了 1 个内存块。没有堆垃圾处理,O(1)。
  2. 您只需要访问指向内存块的指针,然后就可以直接找到所需的元素。
  3. 所有矩阵在内存中都是连续的,这是缓存友好的。

在那些日子里,单个缓存未命中意味着数十或数百个计算周期的丢失,不要低估缓存友好性方面。

顺便说一句,您可能没有提到一种更好的方法:使用众多矩阵库中的一个,它会自动为您处理此问题并提供良好的支持工具(例如 SSE 加速矩阵运算)。一个这样的库是 Eigen , 但还有很多其他的。

→ 你想做科学计算?让 lib 处理样板和基础知识,这样您就可以专注于科学计算部分。

关于c++ - 使用 vector 在 C++ 中声明 3D 数组结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54883795/

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