10

我们有一个 C++ 项目,其中有几个大型静态数据表(结构数组)由预处理工具生成并编译到我们的项目中。到现在我们一直在使用VC++ 2008,但是准备移到2010,这些数据表突然需要很长的时间来编译。

例如,一个这样的表有大约 3,000 个条目,每个条目都是一个包含多个整数和指针的结构,所有这些都是静态初始化的。这个文件在 VC++ 2008 中编译需要大约 15 秒,但在 VC++ 2010 中需要 30分钟

作为一个实验,我尝试将这个表平均分成 8 个表,每个表都在自己的 .cpp 文件中,每个表在 20-30 秒内编译。这让我觉得编译器内部的东西在这些表的长度上是 O(n^2)。

cl.exe 的内存使用稳定在 400 MB 左右(我的机器有 12 GB 的 RAM),一旦稳定,我就看不到任何 I/O 活动,所以我相信这不是磁盘缓存问题。

有谁知道这里会发生什么?是否有一些编译器功能我可以关闭以恢复正常的编译时间?

以下是表中数据的示例:

//  cid (0 = 0x0)
{
    OID_cid,
    OTYP_Cid,
    0 | FOPTI_GetFn,
    NULL,
    0,
    NULL,
    (PFNGET_VOID) static_cast<PFNGET_CID>(&CBasic::Cid),
    NULL,
    CID_Basic,
    "cid",
    OID_Identity,
    0,
    NULL,
},

//  IS_DERIVED_FROM (1 = 0x1)
{
    OID_IS_DERIVED_FROM,
    OTYP_Bool,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicIS_DERIVED_FROM,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "IS_DERIVED_FROM",
    OID_Nil,
    0,
    &COptionInfoMgr::s_aFnsig[0],
},

//  FIRE_TRIGGER_EVENT (2 = 0x2)
{
    OID_FIRE_TRIGGER_EVENT,
    OTYP_Void,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicFIRE_TRIGGER_EVENT,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "FIRE_TRIGGER_EVENT",
    OID_Nil,
    0,
    NULL,
},

//  FIRE_UNTRIGGER_EVENT (3 = 0x3)
{
    OID_FIRE_UNTRIGGER_EVENT,
    OTYP_Void,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicFIRE_UNTRIGGER_EVENT,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "FIRE_UNTRIGGER_EVENT",
    OID_Nil,
    0,
    NULL,
},

如您所见,它包括各种整数和枚举以及一些文字字符串、函数指针和指向其他静态数据表的指针。

4

5 回答 5

6

可能值得关闭此文件的所有优化(无论如何它不会给你买任何东西),以防它是 N^2 的优化器。

于 2011-10-25T20:54:27.867 回答
5

我遇到了同样的问题。有一个包含大约 40'000 个元素的 const 数据数组。编译时间约为 15 秒。当我从“const uint8_t pData[] = { ... }”更改为“ static const uint8_t pData[] = { ... }”时,编译时间下降到不到 1 秒。

于 2013-07-09T07:44:44.353 回答
1

我见过(不记得在哪里)将大型静态数据直接转换为目标文件的技术。然后,您的 C++ 代码将数组声明为extern,并且链接器将两者匹配在一起。这样,数组数据根本不会经过编译步骤。

Microsoft C/C++ 工具CVTRES.exe的工作原理类似,但它不生成符号,而是生成一个单独的资源部分,需要特殊的 API 才能访问 ( FindResource, LoadResource, LockResource)。

啊,这是我记得找到的工具之一:bin2coff 作者有一大堆相关工具


或者,您可以尝试减少依赖关系,以便特定源文件永远不需要重新编译。然后最小重建将自动使用现有的 .obj 文件。甚至可能将该 .obj 文件检查到源代码管理中。

于 2011-10-25T18:20:01.860 回答
1

您可以尝试在 C/C++ 设置中关闭 Pure MISL CLR 支持。为我工作。

于 2011-11-11T04:40:02.537 回答
0

尝试使您的数组静态常量,这在我看到的类似情况下减少了编译时间(但不是文件大小)到无形的。

于 2012-05-11T08:41:02.110 回答