gnz*_*lbg 5 c++ simd intrinsics constexpr c++14
设置:
我有一个使用 SIMD 内在函数的函数,并希望在一些 constexpr 函数中使用它。
为此,我需要使其成为 constexpr。但是,SIMD 内在函数没有标记为 constexpr,编译器的常量评估器无法处理它们。
我尝试用执行相同操作的 C++ constexpr 实现替换 SIMD 内在函数。该函数在运行时变慢了 3.5 倍,但我能够在编译时使用它(是吗?)。
问题:
如何在常量表达式中使用此函数而不会在运行时减慢程序速度?
一些想法:
更务实的解决方案是:
无论如何,我愿意接受任何解决我问题的建议。
提示:
__builtin_constant_p
来检测函数参数是否都是常量表达式,在这种情况下,编译器希望至少尝试在编译时评估函数。失败的尝试:
我会这样做
constexpr int doit(int input, bool inconst = false) {
return inconst ? doitconsty(input) : doitfast(input);
}
Run Code Online (Sandbox Code Playgroud)
如果调用是在可以调用以在运行时或编译时执行某些操作的函数doit
内部constexpr
,则只需转发标志
constexpr int f(int n, bool inconst = false) {
/* ... */
int importantInt = doit(n / 42, inconst);
/* ... */
return magicResult;
}
Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,任何constexpr
评价都有其开始的地方。通过inconst
那里
enum foo { bar = f(256, true) }
Run Code Online (Sandbox Code Playgroud)
如果您处于运行时世界,只需f
像其他任何事情一样调用即可
int main() { std::cout << "test-case: " << f(256); }
Run Code Online (Sandbox Code Playgroud)
应该注意的是,这对运算符不起作用,因为你不能在那里添加布尔参数。相反,您可以以某种不同的方式传递该值,如果这适合您的话(对于像int
and这样的原始值bool
,我们也不能重载运算符)。
template<typename T>
struct maybe_const_value {
T t;
bool isconst;
};
enum foo { bar = maybe_const_value{256, true} % magicTransform };
int main() { return maybe_const_value{265} % magicTransform; }
Run Code Online (Sandbox Code Playgroud)
然后运算符函数可以检查input.isconst
并用作input.t
实际值。