简体   繁体   English

使用大型静态数组的Visual C ++ 2010中的长编译时间

[英]Long compile times in Visual C++ 2010 with large static arrays

We have a C++ project in which there are several large static data tables (arrays of structs) generated by an preprocessing tool and compiled into our project. 我们有一个C ++项目,其中有几个由预处理工具生成并编译到我们项目中的大型静态数据表(结构数组)。 We've been using VC++ 2008 up to now, but are preparing to move to 2010, and these data tables are suddenly taking a very long time to compile. 到目前为止,我们一直在使用VC ++ 2008,但是准备进入2010年,这些数据表突然需要很长时间才能编译。

As an example, one such table has about 3,000 entries, each of which is a struct containing several ints and pointers, all initialized statically. 例如,一个这样的表有大约3,000个条目,每个条目都是一个包含几个整数和指针的结构,所有这些都是静态初始化的。 This one file took ~15 seconds to compile in VC++ 2008, but is taking 30 minutes in VC++ 2010! 这个文件在VC ++ 2008中编译需要大约15秒,但在VC ++ 2010中需要30 分钟

As an experiment, I tried splitting this table evenly into 8 tables, each in its own .cpp file, and they compile in 20-30 seconds each. 作为一个实验,我尝试将此表均匀地分成8个表,每个表都在自己的.cpp文件中,并且每个表在20-30秒内编译。 This makes me think that something inside the compiler is O(n^2) in the length of these tables. 这让我觉得编译器内部的东西在这些表的长度上是O(n ^ 2)。

Memory usage for cl.exe plateaus at around 400 MB (my machine has 12 GB of RAM), and I do not see any I/O activity once it plateaus, so I believe this is not a disk caching issue. cl.exe平台的内存使用量大约为400 MB(我的机器有12 GB的RAM),一旦它处于高位状态,我看不到任何I / O活动,所以我认为这不是磁盘缓存问题。

Does anyone have an idea what could be going on here? 有谁知道这里会发生什么? Is there some compiler feature I can turn off to get back to sane compile times? 是否有一些编译器功能我可以关闭以恢复正常的编译时间?

Here is a sample of the data in the table: 以下是表中数据的示例:

//  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,
},

As you can see, it includes various ints and enums as well as a few literal strings, function pointers and pointers into other static data tables. 如您所见,它包括各种整数和枚举,以及一​​些文字字符串,函数指针和指向其他静态数据表的指针。

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

I had this very same problem. 我遇到了同样的问题。 There was a const array of data that had approx 40'000 elements. 有一个const数组,有大约40'000个元素。 Compile time was about 15 seconds. 编译时间约为15秒。 When I changed from "const uint8_t pData[] = { ... }" to " static const uint8_t pData[] = { ... }" compile time went down to less than 1 second. 当我从“const uint8_t pData [] = {...}”更改为“ static const uint8_t pData [] = {...}”时,编译时间降至不到1秒。

I've seen (can't remember where) a technique for converting large static data directly into object files. 我已经看到(不记得在哪里)一种将大型静态数据直接转换为目标文件的技术。 Your C++ code then declares the array as extern , and the linker matches the two together. 然后,您的C ++代码将数组声明为extern ,并且链接器将两者匹配在一起。 That way the array data never undergoes a compilation step at all. 这样,数组数据根本就不会经历编译步骤。

The Microsoft C/C++ tool CVTRES.exe worked on a similar principle, but it didn't generate symbols, but a separate resource section that needed special APIs to access ( FindResource , LoadResource , LockResource ). Microsoft C / C ++工具CVTRES.exe工作原理类似,但它不生成符号,而是需要特殊API访问的单独资源部分( FindResourceLoadResourceLockResource )。

Ahh, here's one of the tools I remembered finding: bin2coff The author has a whole bunch of related tools 啊,这是我记得找到的工具之一: bin2coff作者有一大堆相关工具


Alternatively, you can try to reduce the dependencies, so that the particular source file never needs recompilation. 或者,您可以尝试减少依赖项,以便特定的源文件永远不需要重新编译。 Then minimal rebuild will automatically use the existing .obj file. 然后最小重建将自动使用现有的.obj文件。 Maybe even check that .obj file into source control. 甚至可以将.obj文件检查到源代码管理中。

You can try turning off Pure MISL CLR support in the C/C++ settings. 您可以尝试在C / C ++设置中关闭Pure MISL CLR支持。 Worked for me. 为我工作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM