10

我正在尝试使用OpenCL来提高我们软件的速度。我们经常使用地图,为了简化,将地图表示为 std::vector< std::vector >。OpenCL API 将原始 c 风格的指针作为参数,例如上面例子中的 int*。

我的问题:

  • stl 中是否有实现保证向量在内部在内存中是连续的?
  • 我可以安全地将 std::vector 转换为 int* 并期望它起作用吗?
  • 在向量向量的情况下,我仍然可以假设这是正确的吗?我希望向量能够保存其他状态数据,或对齐问题,或者其他东西......
  • 解决这个问题的最佳方法是什么?编写一个自定义的 2d 数据结构,它包含一个内部的、连续的内存缓冲区并使用它?我必须从向量中复制很多...

谢谢。

4

4 回答 4

18

stl 中是否有实现保证向量在内部在内存中是连续的?

从 C++03 开始​​,是的,向量保证使用连续存储。(在 C++98 中,有一个意外漏洞,因此实现可以假设使用非连续存储,但它在 2003 年标准修订版中得到修复 - 并且没有实现实际使用非连续存储,因为它是可怕的想法)

我可以安全地将 std::vector 转换为 int* 并期望它起作用吗?

通常的方式是&v[0]。(&*v.begin()可能也可以,但我似乎记得标准中有一些蓬松的措辞使得这不是 100% 可靠)

不,你为什么希望它起作用?向量是一个类。它不是指针。它只包含一个指针。

在向量向量的情况下,我仍然可以假设这是正确的吗?我希望向量能够保存其他状态数据,或对齐问题,或者其他东西......

无论您在其中存储什么,该向量的行为都相同。如果你创建一个向量向量,你最终会得到一个包含指向堆分配数组的指针的对象,其中每个元素都是一个对象,其中包含指向堆分配数组的指针。

至于你应该如何处理这个问题,这取决于很多因素。你的总数据集有多大?您可能希望连续分配整个表。对于向量的向量,每一行都是一个单独的分配。

于 2009-09-07T10:23:32.533 回答
5
  • 在 stl 中是否有实现保证向量在
    内部在内存中是连续的

是的,它是一个动态数组。标准保证向量内的对象是连续存储的。

  • 我可以安全地将 std::vector 转换为 int* 并期望它起作用吗?

不,但您可以使用 begin() 并将其用作指针。

  • 在 stl 中是否有实现保证向量在
    内部在内存中是连续的

不,因为向量可能包含一些内部成员变量,所以整个二维数组不会是连续的内存位置

于 2009-09-07T10:29:31.693 回答
4

stl 中是否有实现保证向量在内部在内存中是连续的?

虽然我不能在这里引用标准,但我已经看到假设这种布局的高质量库中的代码(即POCO)。

我可以安全地将 std::vector 转换为 int* 并期望它起作用吗?

具体来说,您不能重铸矢量本身。但是,我看到了以下代码:

std::vector<int> vec;
int* ptr = &vec[0];

在向量向量的情况下,我仍然可以假设这是正确的吗?我希望向量能够保存其他状态数据,或对齐问题,或者其他东西......

您可能无法将向量向量转换为线性数组。每个向量都会保留自己的内存范围,您不能期望所有这些范围都是连续的。

于 2009-09-07T10:21:24.317 回答
3

您在评论中提到您最多使用 2500x2500xsizeof(double) 数据。在这种情况下,我建议使用单个向量而不是向量的向量。如果您愿意,可以在向量中分配 NxM 元素并将其包装在公开二维索引的类中。您以最小的开销获得向量的所有好处,并且您的所有数据仍在连续内存中以进行快速处理。

于 2009-09-07T19:56:43.367 回答