Что является эквивалентом параметра функции constexpr?

Мы пытаемся ускорить некоторый код в Clang и Visual C++ (GCC и ICC в порядке). Мы думали, что можем использовать constexpr сказать Clang, что значение является постоянной времени компиляции, но оно вызывает ошибку компиляции:

$ clang++ -g2 -O3 -std=c++11 test.cxx -o test.exe
test.cxx:11:46: error: function parameter cannot be constexpr
unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
                                             ^
1 error generated.

Вот сокращенный случай:

$ cat test.cxx
#include <iostream>

unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate);

int main(int argc, char* argv[])
{
  std::cout << "Rotated: " << RightRotate(argc, 2) << std::endl;
  return 0;
}

unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
{
  // x = value; y = rotate
  __asm__ ("rorl %1, %0" : "+mq" (value) : "I" ((unsigned char)rotate));
  return value;
}

GCC и ICC будут делать правильные вещи. Они признают ценность как 2 в выражении RightRotate(argc, 2) не может измениться по законам физической вселенной, как мы их знаем, и это будет лечить 2 в качестве постоянной времени компиляции и распространения ее в коде сборки.

Если мы удалим constexprзатем Clang и VC++ ассемблируют функцию в rotate REGISTERчто в 3 раза медленнее, чем rotate IMMEDIATE,

Как мы скажем Clang параметр функции rotate является постоянной времени компиляции, и она должна быть собрана в rotate IMMEDIATE а не rotate REGISTER?

1 ответ

Для этого вы можете использовать не типовые аргументы шаблона:

template <unsigned int rotate> RightRotate(unsigned int value) {
     ...
}

Затем вы бы призвали его как

RightRotate<137>(argument); // rotate is 137 here
Другие вопросы по тегам