Можно ли инициализировать массив во время компиляции, чтобы это не занимало времени во время выполнения? - PullRequest
0 голосов
/ 13 июля 2020

Если, например, я хочу создать Сито Эратосфена до 2 миллионов, это займет немного времени во время выполнения. Есть ли способ сократить время выполнения с помощью метапрограммирования?

Код для сита (инициализирует std :: bitset до const MILLION):

void initCiur(std::bitset<MILLION> &c)
{
    c[0] = c[1] = 1;
    for (int i=4; i <= MILLION; i+=2)
        c[i] = 1;
    for (int i=3; i*i <= MILLION; i+=2)
        if (!c[i])
            for (int j=3*i; j <= MILLION; j+=2*i)
                c[j] = 1;
}

1 Ответ

1 голос
/ 13 июля 2020

Есть ли способ сократить время выполнения с помощью метапрограммирования?

Конечно, да. Я понимаю « метапрограммирование » очень широко, как любую программу, генерирующую код (а не только умные шаблоны C ++).

В большинстве реализаций C ++ (например, при использовании некоторых недавних G CC компилятор в некоторых GNU / Linux операционных системах), единица перевода C ++ практически представляет собой текстовый файл . Прочтите также стандарт C ++ 11 n3337 .

Так что просто настройте свой инструмент автоматизации сборки (например, GNU make или ninja От ) до сгенерировать во время сборки (возможно, с помощью сценария Python или Guile , или вашей метапрограммы C ++) некоторого файла C ++ или некоторого файла это будет #include -d в другом месте. Или напишите свой G CC плагин , сделав это.

Кстати, эта идея не нова: ANTLR и GNU bison или Qt или SWIG делают это (и последние компиляторы G CC -eg G CC 10 - имеют дюжину специализированных генераторов кода C ++). Так и сделал заброшенный G CC MELT . И так же RefPerSys или bismon (для простых чисел, используемых в хэш-таблицах). Части файла primes_rps.cc были сгенерированы машиной (см. Комментарии внутри него).

В некоторых случаях, умный оптимизирующий компилятор может оптимизировать constexpr вещей. Помните о теореме Райса, которая утверждает, что всегда не всегда возможно грамотно оптимизировать. См. Также этот черновик отчета.

Вас также могут заинтересовать библиотеки для генерации кода, такие как asmjit или libgccjit , или создание плагины во время выполнения (на Linux вы должны использовать dlopen (3) и dlsym (3) , но сначала прочтите C ++ dlopen mini-howto тогда как писать разделяемые библиотеки ).

PS. с другими операционными системами (например, Windows) и компиляторами C ++ все может быть иначе, но большинство идей, приведенных выше, можно использовать повторно. Прочтите документацию к вашему C ++ компилятору и вашей операционной системе . В подходах кросс-компиляции вам могут понадобиться дополнительные приемы.

...