gpt4 book ai didi

performance - 点乘积性能与 SSE 指令

转载 作者:行者123 更新时间:2023-12-03 17:12:09 27 4
gpt4 key购买 nike

通过 dpps 计算两个向量的点积是否更快?指令形成SSE 4.1指令集或通过使用一系列addps , shufpsmulps来自上交所1?

最佳答案

答案可能与上下文密切相关,并且完全取决于它在更大的代码流中的使用位置和方式,以及您所使用的硬件。

从历史上看,当英特尔推出新指令时,他们并没有专门为其投入太多硬件区域。如果它得到足够的采用和使用,他们会在后代中投入更多的硬件。因此,就原始 ALU 性能而言,与 SSE2 方式相比,Penryn 上的 _mm_dp_ps 并没有特别令人印象深刻。另一方面,它确实需要较少的指令缓存中的指令,因此当更紧凑的编码性能更好时,它可能会有所帮助。

_mm_dp_ps 的真正问题是作为 SSE 4.1 的一部分,你不能指望它会在每台现代 PC 上得到支持(Valve 的 Steam 硬件调查显示,对于游戏玩家来说,它的支持率约为 85%) 。因此,您最终不得不编写 protected 代码路径而不是直线代码,而这通常花费的成本超过了使用指令所获得的好处。

如果您正在为保证支持它的 CPU 制作二进制文件,那么它很有用。例如,如果您使用 /arch:AVX(甚至 /arch:AVX2)进行构建,要么是因为您的目标是 Xbox One 等固定平台,要么是正在构建多个您的 EXE/DLL 版本,您可以假设 SSE 4.1 也将受到支持。

这实际上就是DirectXMath是:

inline XMVECTOR XMVector4Dot( FXMVECTOR V1, FXMVECTOR V2 )
{
#if defined(_XM_NO_INTRINSICS_)

XMVECTOR Result;
Result.vector4_f32[0] =
Result.vector4_f32[1] =
Result.vector4_f32[2] =
Result.vector4_f32[3] = V1.vector4_f32[0] * V2.vector4_f32[0] + V1.vector4_f32[1] * V2.vector4_f32[1] + V1.vector4_f32[2] * V2.vector4_f32[2] + V1.vector4_f32[3] * V2.vector4_f32[3];
return Result;

#elif defined(_M_ARM) || defined(_M_ARM64)

float32x4_t vTemp = vmulq_f32( V1, V2 );
float32x2_t v1 = vget_low_f32( vTemp );
float32x2_t v2 = vget_high_f32( vTemp );
v1 = vpadd_f32( v1, v1 );
v2 = vpadd_f32( v2, v2 );
v1 = vadd_f32( v1, v2 );
return vcombine_f32( v1, v1 );

#elif defined(__AVX__) || defined(__AVX2__)

return _mm_dp_ps( V1, V2, 0xff );

#elif defined(_M_IX86) || defined(_M_X64)

XMVECTOR vTemp2 = V2;
XMVECTOR vTemp = _mm_mul_ps(V1,vTemp2);
vTemp2 = _mm_shuffle_ps(vTemp2,vTemp,_MM_SHUFFLE(1,0,0,0));
vTemp2 = _mm_add_ps(vTemp2,vTemp);
vTemp = _mm_shuffle_ps(vTemp,vTemp2,_MM_SHUFFLE(0,3,0,0));
vTemp = _mm_add_ps(vTemp,vTemp2);
return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2));

#else
#error Unsupported platform
#endif
}

This of course assumes you are going to use the 'scalar' result of a dot-product in additional vector operations. By convention, DirectXMath returns such scalars 'splatted' across the return vector.

参见DirectXMath: SSE4.1 and SSE4.2

更新:虽然不如 SSE/SSE2 支持那么普遍,但对于不使用 /arch:AVX 构建的情况,您可能需要 SSE3 支持>/arch:AVX2 并尝试:

inline XMVECTOR XMVector4Dot(FXMVECTOR V1, FXMVECTOR V2)
{
XMVECTOR vTemp = _mm_mul_ps(V1,V2);
vTemp = _mm_hadd_ps( vTemp, vTemp );
return _mm_hadd_ps( vTemp, vTemp );
}

也就是说,目前尚不清楚 hadd 在大多数情况下至少在点积方面优于 SSE/SSE2 add 和 shuffle 解决方案。

关于performance - 点乘积性能与 SSE 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37879678/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com