Длительное время компиляции в Visual C ++ 2010 с большими статическими массивами - PullRequest
10 голосов
/ 25 октября 2011

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

Например, одна такая таблица содержит около 3000 записейкаждая из которых представляет собой структуру, содержащую несколько целых и указателей, все статически инициализируются.Этот один файл занимает ~ 15 секунд для компиляции в VC ++ 2008, но занимает 30 минут в VC ++ 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,
},

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

Ответы [ 5 ]

6 голосов
/ 26 октября 2011

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

4 голосов
/ 09 июля 2013

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

1 голос
/ 11 ноября 2011

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

1 голос
/ 25 октября 2011

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

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

Ааа, вот один из инструментов, который я запомнил, обнаружив: bin2coff Автор имеет aцелый набор связанных инструментов


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

0 голосов
/ 11 мая 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...