Длительное время компиляции в Visual С++ 2010 с большими статическими массивами

У нас есть проект на С++, в котором есть несколько больших статических таблиц данных (массивов структур), созданных инструментом предварительной обработки и скомпилированных в наш проект. Мы используем VС++ 2008 до сих пор, но готовимся к переходу на 2010 год, и эти таблицы данных внезапно занимают очень много времени для компиляции.

В качестве примера одна такая таблица содержит около 3000 записей, каждая из которых представляет собой структуру, содержащую несколько int и указателей, причем все они инициализируются статически. Этот файл потребовал ~ 15 секунд для компиляции в VС++ 2008, но занимает около 10 минут в VС++ 2010!

В качестве эксперимента я попытался равномерно распределить эту таблицу на 8 таблиц, каждый в своем собственном .cpp файле, и они скомпилируются через 20-30 секунд каждый. Это заставляет меня думать, что что-то внутри компилятора равно O (n ^ 2) в длине этих таблиц.

Использование памяти для плакатов cl.exe на уровне около 400 МБ (у моей машины 12 ГБ ОЗУ), и я не вижу никаких операций ввода-вывода после того, как они появились на плато, поэтому я считаю, что это не проблема кэширования диска.

Есть ли у кого-нибудь идея, что здесь происходит? Есть ли какая-либо функция компилятора, которую я могу отключить, чтобы вернуться к разумным времени компиляции?

Вот пример данных в таблице:

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

Как вы можете видеть, он включает в себя различные int и перечисления, а также несколько литералов, указатели на функции и указатели в другие таблицы статических данных.

Ответ 1

Возможно, стоит отключить всю оптимизацию в этом файле (он все равно не купит вам ничего), если это оптимизатор, идущий N ^ 2.

Ответ 2

У меня была такая же проблема. Был массив данных const, в котором было около 40 000 элементов. Время компиляции составляло около 15 секунд. Когда я изменился с "const uint8_t pData [] = {...}" до " static const uint8_t pData [] = {...}" время компиляции сократилось до менее 1 секунды.

Ответ 3

Я видел (не могу вспомнить, где) метод преобразования больших статических данных непосредственно в объектные файлы. Затем ваш код на С++ объявляет массив как extern, а компоновщик сопоставляет два вместе. Таким образом, данные массива никогда не претерпевают этап компиляции.

Инструмент Microsoft C/С++ CVTRES.exe работал по аналогичному принципу, но он не генерировал символы, а отдельный раздел ресурсов, для которого требовались специальные API для доступа (FindResource, LoadResource, LockResource).

Ahh, здесь один из инструментов, которые я помню, нашел: bin2coff Автор целая куча связанных инструментов


В качестве альтернативы вы можете попытаться уменьшить зависимости, чтобы конкретный исходный файл никогда не нуждался в перекомпиляции. Тогда минимальная перестройка автоматически будет использовать существующий файл .obj. Возможно, даже проверьте, что .obj файл в исходный код.

Ответ 4

Вы можете попробовать отключить поддержку Pure MISL CLR в настройках C/С++. Работал для меня.

Ответ 5

Попробуйте сделать свой массив static const, этот сокращенный период компиляции (но не файл) в аналогичном случае, который я видел до неосязаемого.