这是什么是constexpr的函数参数等效形式?的延续。在原问题中,我们试图加速一些在Clang和VC++下执行移位和旋转的代码。由于Clang和VC++将移位/旋转量视为变量(即不是
当我尝试参数化移位量和字长时,结果为:
这是测试程序。它比需要的稍微大一点,以便人们可以看到我们需要处理
我曾根据旋转实现的方式经历了多次错误消息迭代。其他错误消息包括
我该如何参数化移位量,以便Clang和VC++可以按预期优化函数调用?
constexpr
),它们不能对代码进行良好的优化。当我尝试参数化移位量和字长时,结果为:
$ g++ -std=c++11 -march=native test.cxx -o test.exe
test.cxx:13:10: error: function template partial specialization is not allowed
uint32_t LeftRotate<uint32_t, unsigned int>(uint32_t v)
^ ~~~~~~~~~~~~~~~~~~~~~~~~
test.cxx:21:10: error: function template partial specialization is not allowed
uint64_t LeftRotate<uint64_t, unsigned int>(uint64_t v)
^ ~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
这是测试程序。它比需要的稍微大一点,以便人们可以看到我们需要处理
uint32_t
和 uint64_t> (更不用说 uint8_t
、uint16_t
和其他类型了)。
$ cat test.cxx
#include <iostream>
#include <stdint.h>
template<typename T, unsigned int R>
inline T LeftRotate(unsigned int v)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
static const unsigned int MASK = THIS_SIZE-1;
return T((v<<R)|(v>>(-R&MASK)));
};
template<uint32_t, unsigned int R>
uint32_t LeftRotate<uint32_t, unsigned int>(uint32_t v)
{
__asm__ ("roll %1, %0" : "+mq" (v) : "I" ((unsigned char)R));
return v;
}
#if __x86_64__
template<uint64_t, unsigned int R>
uint64_t LeftRotate<uint64_t, unsigned int>(uint64_t v)
{
__asm__ ("rolq %1, %0" : "+mq" (v) : "J" ((unsigned char)R));
return v;
}
#endif
int main(int argc, char* argv[])
{
std::cout << "Rotated: " << LeftRotate<uint32_t, 2>((uint32_t)argc) << std::endl;
return 0;
}
我曾根据旋转实现的方式经历了多次错误消息迭代。其他错误消息包括
no function template matches function template specialization...
。使用template <>
似乎产生了最难以理解的一种错误消息。我该如何参数化移位量,以便Clang和VC++可以按预期优化函数调用?
rorx
生成。接下来是VC++生成,看看情况如何。 - jww