【问题标题】:Long compilation for an initialization of large vector of vectors大型向量初始化的长编译
【发布时间】:2018-09-07 05:12:46
【问题描述】:

我有一个非常大的常量二维数组要存储在 C++ 文件中。 维度约为 1,000,000 行,每行 2 到 10 个元素,以 uint8_t 为元素。

每行中元素的数量是可变的,我想对行使用向量,并且可能对整个数组使用向量向量,所以我尝试了 3 种初始化方法

const uint8_t array[1000000][10] = {{...},...,{...}};              /* Case 1 */
const std::vector<uint8_t> array[1000000] = {{...},...,{...}};     /* Case 3 */
const std::vector<std::vector<uint8_t>> array = {{...},...,{...}}; /* Case 2 */

三种情况下使用g++编译的差别很大。

案例 1 编译速度很快,但我担心会浪费一些空间来保持对齐?案例 2 和案例 3 是否有所不同?

案例 2 和案例 3 需要很长时间才能编译。添加-ftime-report 表明g++“阶段选择和生成”步骤需要很长时间。

知道要更改代码和/或加快编译速度吗?

【问题讨论】:

  • 为什么需要这么大的常数向量?
  • 这些是非常长的计算的输出,需要硬编码到代码中以避免重新计算。
  • 您可以将“整个数据”写入单独的程序集文件,并将该文件和 c++ 源代码链接到单个二进制文件中。与您的情况相比,这将非常快。
  • sizeof(vector) 基本上是 2 *sizeof(T*) + std::size_t,它应该优于 10 与您的编译器/架构。所以你不应该失去 Case1 的空间(但应该跟踪内部的“数组大小”)
  • "compiles fast" 真的是编译时间比较而不是运行时间(内存分配开销)吗?

标签: c++ large-data


【解决方案1】:

您可以将“全部数据”写入单独的程序集文件,并将该文件和 c++ 源代码链接到单个二进制文件中。与您的情况相比,这将非常快。

示例汇编文件:

 .globl large_data
    .section .rodata
    .p2align 5
    .type large_data, "object"
    .size large_data, <insert_size_here>
large_data:

    .byte 77,90,144,0,3,0,0,0,4,0,0,0,255,2..... and so on

示例 C++ 代码:

extern const uint8_t large_data [];

如果将这些来源链接在一起,则可以直接访问数据,例如:

uint8_t x = large_data[0];

这样,你只需要编译一次汇编文件。

【讨论】:

  • 为了示例,假设A[][] 的每一行都包含 1 个元素,但其中一行包含 10 个元素。然后我会将您的外部变量转换为(uint8_t (*)[10]),然后程序集文件中有大量未使用的空间,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多