【问题标题】:How to create a huge array in modern C++?如何在现代 C++ 中创建一个巨大的数组?
【发布时间】:2020-08-29 21:57:06
【问题描述】:

我想为大量数据(例如整数)创建数组。 该数组将表示二维矩阵。
我不能使用 STL,因为它将与 CUDA 一起运行。
我想知道以下选项的优缺点是什么:

  • int arr[SIZE] - 这是创建数组的最简单方法。它是在堆栈上分配的,因此它将是最快的 - 这里的问题是它的大小非常有限。
  • int* arr = new int[SIZE]
  • int** arr = new int*[DIM1] - 如果我们看效率,这是最坏的情况,但它允许存储 INT_MAX * INT_MAX 值。

我正在考虑第二种选择。我电脑上的 Sizeof(int) 是 32 位。我认为对于某些测试用例来说它可能太小了(如果我使用大于 32k x 32k 的矩阵)。

第三个选项似乎是最灵活的,但我听说这不是好的做法。

还有其他方法可以创建这样的数组( > 1B 元素)吗? 是否可以创建大于 INT_MAX/2 长度的一维数组?

【问题讨论】:

  • new int[n]; 操作的参数 (n) 是 size_t 类型(不是 int),如果这有帮助的话(虽然不确定它对 CUDA 有很大的影响) )。
  • "我不能使用 STL,因为它将与 CUDA 一起运行。" 嗯,为什么不呢?您必须将数组复制到 CUDA 的内存中才能使用它,对吗?如果您的 CPU 副本分配来自 std::vector<int> 或其他什么,这有什么关系?
  • "我正在考虑第二个选项。我的计算机上的 Sizeof(int) 是 32 位。我认为对于某些测试用例来说它可能太小了(如果我使用大于 32k x 的矩阵32k)." 32 位 (unsigned int) 将允许矩阵大小为 2^32 x 2^32,而不是 32k x 32k。
  • 我不能使用 STL -- 你可能不知道,new int[]vector 正在做的事情。 std::vector<>::data() 函数为您提供指向该缓冲区的指针。
  • @SzymonŻak "我认为这是一个 int,而不是 unsigned int。" 为什么会有人这么认为?允许负大小的数组有什么意义?如 cmets 中所述,实际大小是 size_t 类型。可以大于int,或unsigned int,但绝对是unsigned

标签: c++ arrays c++11 multidimensional-array data-structures


【解决方案1】:

如何在现代 C++ 中创建一个巨大的数组?

使用动态分配1。在标准的托管 C++ 中,它通常使用 std::vector 创建。

我不能使用 STL,因为它将与 CUDA 一起运行。

你是指标准库吗?在这种情况下,解决方案是使用另一个可以与 CUDA 一起运行的容器。

int* arr = new int[SIZE]

您确定new[] 的使用不受限制,原因与容器的使用受限相同吗?如果容器不是,我希望new[] 不能成为一个选项。目前尚不清楚您的限制究竟是什么。

无论如何,您都不应该使用裸拥有的指针。使用容器或至少使用智能指针。

int** arr = new int*[DIM1]

如果您需要不同长度的行或需要交换行,这可能很有用(忽略使用裸指针来表示所有权,这是不好的)。否则,这与一维数组相比没有任何优势。

是否可以创建大于 INT_MAX/2 长度的一维数组?

假设 32 位 intINT_MAX/2 将是 1 GB。只要您有可用的内存,这在 64 位系统上是没有问题的。在 32 位系统上,可能只是勉强,但您可能没有足够的内存。

但我通常使用 cudaMallocManaged 创建 int*,然后从文件中填充它。所以 std::vector 在这里无济于事,因为我什至不必使用它

如果你使用cudaMallocManaged,那么你就不会使用new[],所以在这里也无济于事。


1 除非数组需要太大以至于不能作为一个整体保存在内存中,否则必须在文件系统中将其创建为文件。

【讨论】:

  • 是的,我的意思是标准库。 std::vector 和 std::array 不能在 CUDA 上创建(除非我们使用推力)。 int[] 和 int[][] 在标准 C++ 中受到限制。实际上,我将所有内容都放在向量中,然后使用 std::vector::data() 将其复制到 CUDA 是个好主意。但是,我通常在 CUDA 上创建数组: int* arr; cudaMallocManaged(&arr, SIZE * sizeof(int));然后从 STDIN 或文件中填充。
  • 您可以创建自己的分配器以在后台调用cudaMallocManaged,然后使用std::vector<int, CudaAllocator<int>> 声明您的向量。
猜你喜欢
  • 2017-07-08
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
相关资源
最近更新 更多