Что является эквивалентом параметра функции 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