C++ 逆平方根内在函数

C++ 逆平方根内在函数,c++,visual-studio,C++,Visual Studio,在标量参数上是否有反平方根、单精度浮点和双精度浮点的编译器内部函数 我可以为压缩SIMD参数(SSE和AVX)找到这些参数,但不能为标量找到它们 任何比平方根除法更快的方法都是受欢迎的。给你 #包括 //与std::sqrt相同 内联浮点sqrt(常量浮点f) { __m128温度=_mm_设置_ss(f); 温度=_mm_sqrt_ss(温度); 返回mm_cvtss_f32(温度); } //比1.0f/std::sqrt快,但精度很低。 内联浮点rsqrt(常量浮点f) { __m128温

在标量参数上是否有反平方根、单精度浮点和双精度浮点的编译器内部函数

我可以为压缩SIMD参数(SSE和AVX)找到这些参数,但不能为标量找到它们

任何比平方根除法更快的方法都是受欢迎的。

给你

#包括
//与std::sqrt相同
内联浮点sqrt(常量浮点f)
{
__m128温度=_mm_设置_ss(f);
温度=_mm_sqrt_ss(温度);
返回mm_cvtss_f32(温度);
}
//比1.0f/std::sqrt快,但精度很低。
内联浮点rsqrt(常量浮点f)
{
__m128温度=_mm_设置_ss(f);
温度=_mm_rsqrt_ss(温度);
返回mm_cvtss_f32(温度);
}
//与std::sqrt相同
内联双sqrt(常数双f)
{
__m128d温度=_mm_设置_sd(f);
温度=_mm_sqrt_sd(温度,温度);
返回_mm_cvtsd_f64(温度);
}
//与1.0/std::sqrt相同
// .... 没有带双精度的rsqrt指令,
//因此,1.0/std::sqrt是最好的。
内联双rsqrt(常数双f)
{
__m128d温度=_mm_设置_sd(f);
温度=_mm_div_sd(_mm_set_sd(1.0),_mm_sqrt_sd(温度、温度));
返回_mm_cvtsd_f64(温度);
}
与std::sqrt()的比较:

如果启用-ffast math(或者在MSVC中启用float precision fast),那么std::sqrt很可能生成与使用内部函数相同的代码。唯一的例外是浮点数的rsqrt(clang将1/sqrt转换为rsqrt+newton-raphson迭代)

显然rsqrt带有一些非常严重的浮动错误。比如说,为OpenGL渲染对一组曲面法线进行归一化可能没什么问题,但对于几乎所有其他方面来说,由于缺乏准确性,这基本上是无用的。(例如,二次公式)

任何“地震3优化rsqrt”的胡说八道都会比直接调用std::sqrt慢很多数量级,但精确度非常差

在游戏行业工作时,至少每个月有一次,一些新人会尝试通过用std::sqrt替换它来“优化”代码。叹息


TL;DR:如果您启用了快速数学,只需使用std::sqrt即可。如果快速数学被禁用,C++标准规定错误代码将被设置为ErNO,这将迫使编译器使用STD库版本。< /强>

相关:@达米安:恐怕这并不能克服内置函数在时间和准确性方面的问题。我还发现了这篇文章的
double
,但我想它会提供类似的性能:rsqrtss(或者作为一个内在的rsqrtss)。一如既往。“我看不到一台是双倍的,只需要使用打包的一台并提取结果即可”。@MikeVine:是的,我知道这些。出于好奇,我刚刚在几台计算机上进行了检查:*1.0f/sqrtf(x)参考速度1.0。*地震:~0.5。*内在:~0.25。因此,地震版本可能正在消失。我现在无法用手臂检查。但我只找到了两个浮点数的vrsqrte_f32指令。我认为没有针对单个值的版本。我不相信您的结果(我怀疑您的评测方法有缺陷)。你是否启用了快速数学?您是否在做一些愚蠢的事情,比如对一个用于rsqrts数组中元素的for循环进行基准测试?(即内存带宽有限)。您是否正在利用sqrt的结果?(即编译器未能为您的测试生成代码)。你是在释放中这样做的吗?太粗鲁了!如果你认为你自己的结果会和我的有那么大的不同,请在这里发布你自己的结果。在我的电脑上,quake版本大约比1/sqrt快两倍,intrinsics版本快四倍。这对你来说还不够吗?