首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带SSE指令的点乘积性能

带SSE指令的点乘积性能
EN

Stack Overflow用户
提问于 2016-06-17 10:48:07
回答 1查看 3.9K关注 0票数 2

用SSE4.1指令集中的dpps指令或使用SSE 1中的一系列addpsshufpsmulps来计算两个向量的点积是否更快?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-17 15:09:03

答案可能是非常上下文化的,并且完全取决于它在更大的codeflow中的位置和使用方式,以及您所使用的硬件。

从历史上看,当英特尔推出新的指令时,他们并没有在硬件方面投入太多的精力。如果它被采纳并得到足够的使用,他们就会在后代中投入更多的硬件。因此,与SSE2方式相比,Penryn上的SSE2在原始ALU性能方面并不特别令人印象深刻。另一方面,它确实需要i-缓存中较少的指令,以便在更紧凑的编码能够更好地执行时,它可能会有所帮助。

_mm_dp_ps真正的问题在于它是SSE4.1的一部分,你不能指望它在每台现代PC上都能得到支持(阀门的蒸汽硬件调查将游戏玩家的比例定在85%左右)。因此,您最终不得不编写有保护的代码路径,而不是直线代码,而这通常比使用指令所带来的好处还要高。

它的有用之处在于,如果您要为一个保证支持它的CPU生成二进制文件。例如,如果您使用/arch:AVX (甚至/arch:AVX2)构建,或者是因为您的目标是Xbox这样的固定平台,或者是正在构建多个版本的EXE/DLL,您可以假设SSE4.1也将得到支持。

这实际上是DirectXMath所做的工作:

代码语言:javascript
复制
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
}

当然,这假设您将在附加向量操作中使用点积的“标量”结果。按照惯例,DirectXMath在返回向量中返回这样的标量“飞溅”。

请参阅DirectXMath: SSE4.1和SSE4.2

更新:虽然不像SSE/SSE 2支持的那样普遍存在,但是对于没有使用/arch:AVX/arch:AVX2构建的情况,您可以要求SSE3支持,然后尝试:

代码语言:javascript
复制
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添加和洗牌解决方案上的点积。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37879678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档