Может ли оптимизация компилятора c ++ генерировать две версии функции относительно логического аргумента? - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть функция f(int x, float y, char* z, .., bool b).Аргумент b используется только в виде:

if (b) {
 ...
} else {
 ...
}

в различных частях тела функции.По соображениям эффективности я хотел бы эффективно создать две функции f0 и f1, где b имеет значение false и true соответственно, чтобы избежать оценки условия во время выполнения.В то же время, поскольку реализация f довольно долгая, я не хочу явно определять f0 и f1 по отдельности.Есть ли какая-либо функция оптимизации компилятора, которая автоматически порождает эти две функции ветвления во время компиляции?

Может быть, есть лучшие шаблоны проектирования, которые полностью избегают этого мышления?Имейте в виду, что условное b может быть оценено в массивном цикле.

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Шаблон позволяет факторизовать этот вид кода, а C ++ 17 позволяет его чисто с if constexpr:

template<bool b>
void f(int x, float y, char *z)
{
    // ...
    if constexpr (b)
    {
        // ...
    }
    else
    {
        // ...
    }
    // ...
}

// if you still need runtime dispatch
void f(int x, float y, char *z, bool b)
{
    return b ? f<true>(x, y, z) : f<false>(x, y, z);
}

Без if constexpr, нет гарантии, что во время выполнения ветвления нет, но компилятор может легко сделать это нормально.Поэтому, если вы хотите получить эту гарантию до C ++ 17, вы должны специализировать расходящуюся деталь

  • по специализации:

    template <bool b> void f_impl(..);
    
    template <> void f_impl<true>(..)  { /*..*/ }
    template <> void f_impl<false>(..) { /*..*/ }
    
    template<bool b>
    void f(int x, float y, char *z)
    {
        // ...
        f_impl<b>(..);
        // ...
    }
    
  • илиотправка тегов:

    void f_impl(std::true_type, ..)  { /*..*/ }
    void f_impl(std::false_type, ..) { /*..*/ }
    
    template<bool b>
    void f(int x, float y, char *z)
    {
        // ...
        f_impl(std::integral_constant<bool, b>{}..); // std::bool_constant<b> in C++17 
        // ...
    }
    
0 голосов
/ 28 декабря 2018

Используйте шаблон:

template<bool b>
void f(int x, float y, char *z)
{
    if (b)
    {
        ...
    }
    else
    {
        ...
    }
}

...
if (runtimeCondition)
{
    f<true>(1, 2, "");
}
else
{
    f<false>(1, 2, "");
}
...