Mar*_*ník 5 c++ performance x86 sqrt
我在 C++ 中有一行
c[i] = sqrtf(a[i]);
Run Code Online (Sandbox Code Playgroud)
和汇编代码看起来
002D11D0 vsqrtps ymm0,ymmword ptr a (202D3380h)[eax]
Run Code Online (Sandbox Code Playgroud)
用一条线
c[i] = 1.0f / sqrtf(a[i]);
Run Code Online (Sandbox Code Playgroud)
我有一个集会
00E71210 vrsqrtps ymm1,ymm0
00E71214 vmulps ymm0,ymm1,ymm0
00E71218 vmulps ymm0,ymm0,ymm1
00E7121C vsubps ymm0,ymm0,ymm6
00E71220 vmulps ymm0,ymm0,ymm1
00E71224 vmulps ymm0,ymm0,ymm7
Run Code Online (Sandbox Code Playgroud)
这显然是合理的,因为vrsqrtps
比 快得多vsqrtps
。因此,在平方根的倒数的情况下,调用不准确的函数vrsqrtps
然后进行两次迭代以获得更精确的值会更快。
我的问题是: 是否可以告诉编译器不需要额外的迭代?因此汇编将不需要额外的乘法。~1.5 * 2^-12 的误差对我来说完全足够了,因为我想添加数千个这样的结果,其中许多位的准确性也会下降。我更喜欢一种不将某些汇编代码内联到 C++ 代码中的方法。
(编辑后)编译器命令行:
/GS /Qpar /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /Ox /Ob2 /sdl /Fd"Release\vc141.pdb" /Zc:inline /fp:fast /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /arch:AVX2 /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Ot /Fp"Release\performancetest.pch" /diagnostics:classic
Run Code Online (Sandbox Code Playgroud)
恐怕没有编译器标志来强制降低倒数平方根的计算精度。
但是您可以使用内在函数轻松编写自己的函数,例如:
#include <immintrin.h>
float fast_rsqrt( float x ) {
return _mm_cvtss_f32( _mm_rsqrt_ss( _mm_set_ss( x ) ) );
}
Run Code Online (Sandbox Code Playgroud)
这将在 x86-64 平台上的 Clang、GCC 和 MSVC 编译器中运行。最新的MSVC会为其生成这样的汇编代码:
float fast_rsqrt(float) PROC ; fast_rsqrt
rsqrtss xmm1, xmm0
movaps xmm0, xmm1
ret 0
float fast_rsqrt(float) ENDP ; fast_rsqrt
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/dE47M6a8x
归档时间: |
|
查看次数: |
586 次 |
最近记录: |