我们正在尝试加速 Clang 和 Visual C++ 下的一些代码(GCC 和 ICC 也可以)。我们thought我们可以使用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;
}
海合会和国际商会会做正确的事。他们认识到这样的价值观2
在表达式中RightRotate(argc, 2)
根据我们所知的物理宇宙定律,它不能改变,并且它将对待2
作为编译时常量并将其传播到汇编代码中。
如果我们删除constexpr
,然后 Clang 和 VC++ 将函数组装成rotate REGISTER
,比速度慢 3 倍rotate IMMEDIATE
.
我们如何告诉 Clang 函数参数rotate
是一个编译时常量,它应该被组装成rotate IMMEDIATE
而不是一个rotate REGISTER
?