STL容器速度与阵列相比

时间:2013-02-20 19:46:02

标签: c++ arrays performance stl hpc

我刚刚开始研究速度真正重要的科学项目(HPC)。我目前正在设计数据结构。该项目的核心是双值的3D网格,以求解偏微分方程。

由于这里的速度可能比代码的简单性更大,我想知道STL与通常的C风格数组相比如何执行。在我的例子中,因为它是一个3D网格,我想到了a)带有线性索引的一维向量b)3个向量的向量或c)一维c样式数组或d)三维c样式阵列。

我查找了较旧的问题,但我只发现了构建/破坏的问题(这里不重要,因为数据结构只在程序启动时创建一次 - 快速索引和计算很重要)或不同STL的比较容器

感谢您的帮助

4 个答案:

答案 0 :(得分:7)

提前说什么很难(甚至不可能) 相对表现将是。一般来说,在现代机器上, 使用平面向量,并计算其中的索引,将 优于矢量矢量矢量;在旧机器上, 反过来是真的。 (在现代机器上,乘法是 由于地方不佳,通常比页面错过便宜。上 旧机器,乘法是昂贵的,而没有 缓存,所以地方没有什么区别。)

另外,根据机器和库的实现, 使用std::vector这个平面向量可能更多 比使用简单的指针指向内存昂贵(或者它可能 不是 - 你事先无法知道)。我还是会去的 矢量首先,在控制课中仔细包装一切, 如果仍有性能问题,请切换到 指针。

答案 1 :(得分:3)

1D和3D阵列的内存布局将是相同的,类似于线性std::vector的内存布局。我会采用这种方法:一维向量和内联函数,以映射到适当的位置。

另一方面,向量向量具有完全不同的布局,因为向量中的数据不存储在对象内部,而是动态分配和引用。这意味着std::vector<std::vector<int>>中的两个不同行可能位于内存中完全不相关的位置。

答案 2 :(得分:2)

向量将在内部执行您需要手动执行的操作,以便处理单独调整的原始数组,因此只要它们被正确使用,向量应该与执行相同任务的原始数组执行相同的操作。

例如,单个矢量应该与单维c阵列执行相同,矢量矢量应该与使用原始指针数组大致相同,每个指针指向一个数组。< / p>

然而,如果3d阵列具有统一的尺寸大小(即,不是粗糙的阵列),则向量支付额外的成本来单独管理它们的尺寸(例如,它们必须单独存储它们的尺寸)。如果在编译时知道任何尺寸大小,那么最好使用&#39; STL&#39; container&#39; std :: array , because it won't have that unnecessary overhead. You can even have multi-dimentional std :: arrays`:

template<typename T, int Planes, int Rows, Cols>
using Matrix = std::array<std::array<std::array<T,Cols>,Rows>,Planes>;

虽然不是严格要求,但它应该与T arr[Planes][Rows][Cols];相同,但没有原始c数组的问题。

答案 3 :(得分:0)

在HPC中广泛使用的动态分配静态(在分配后的不可更改的维度方面)数组对象是平面数组和涂料向量的组合。基本上这个想法是分配一大块内存,然后构建一个指针树。对于2D数组,树只是指向每行开头的指针的简单线性列表。对于3D阵列,树具有两个级别,并且每个第二级别元素指向来自2D切片的对应于第一级别的行。将涂料矢量树放置在已分配内存的开头,可以直接应用[]索引运算符,例如, A[i][j][k],但必须小心谨慎,因为&A[i]不会是i 2D切片的开头。

这种方法的一个问题是涂料矢量树的尺寸可能会变得非常大。例如,64位计算机上1000x1000x1000阵列的此数据结构的大小为1000x1000x8字节或几乎为8 MiB。这可能会为某些数据访问模式带来宝贵的缓存空间。