【问题标题】:A better SSE2 implementation for float4::set_wxy (and other set-swizzle ops)?float4::set_wxy(和其他 set-swizzle 操作)的更好的 SSE2 实现?
【发布时间】:2012-07-08 05:29:33
【问题描述】:

我正在使用 SSE2/AVX 内在函数在 C++ 中编写符合 HLSL float4 的类型,目前我正在实现 HLSL 中可用于 float4 的所有 set-swizzle 操作。我试图找出一个最佳的 SSE2 实现来处理涉及(swizzle)设置 2 或 3 个组件的 set-swizzle 操作(因为使用一个 SSE shuffle 操作来实现 4-component set-swizzles 是微不足道的)。例如,如果没有至少 4/5 SSE shuffle ops,我想不出更好的方法来实现 say set_wxy,例如:

inline/__forceinline void float4::set_wxy(const float4& x)
{
    float4 tmp2 = *this;
    tmp2.set_wxyz(x);                         // set_wxyz = 1 x _mm_shuffle_ps
    const __m128 xyw_tmp = tmp2.zxyw().data;  // zxyw() = 1 x _mm_shuffle_ps
    const __m128 z_tmp = zxyw().data;         // zxyw() = 1 x _mm_shuffle_ps
    tmp2 = _mm_move_ss(xyw_tmp, z_tmp);
    set_zxyw(tmp2);                           // set_zxyw() = 1 x _mm_shuffle_ps
}

在不使用 SSE2 之外的操作的情况下,是否有人对更好的实施有任何想法?正如我所知道的 SSE4/AVX 中的 _mm_blend_ps ,我将在通过预处理器条件可用时使用它,但我想至少支持一个仅 SSE2 的代码路径。提前致谢!

编辑:此函数的行为示例是:

float4 k(5,5,5,5);
k.set_wxy(float4(1,2,3,4));
// now k == (2, 3, 5, 1)

基本上 set_wxy 使用 x,y,z 的参数按此顺序设置 w,x,y 分量,保留原始 z 值。

【问题讨论】:

  • set_wxy 到底应该做什么?我试图从代码中推断出来,但隐藏的太多了。
  • @harold 好的,我刚刚添加了一些关于这些函数的行为的更多信息,我希望这能澄清一点。感谢阅读。
  • 查看 Windows 8 SDK (DirectXMath.h) 中 DirectXMath 的源代码,它具有非常快的 SSE2 操作,可用于 swizzles 等(并且它的编写符合 DX 和 HLSL)。 TBH,您可能可以直接使用 DX 数学,省去自己的努力
  • @Necrolis 不要相信 DirectXMath 已经为每一个 swizzle 预先编写了函数。你仍然需要编写这个函数。
  • @JohnCalsbeek:XMVectorSelect:msdn.microsoft.com/en-us/library/windows/desktop/… DirectXMath 基本上涵盖了你现在可能想做的所有事情(它甚至有基本的碰撞测试),此外,它已经过优化相当多的使用模板等,因此可以在编译时消除选择开销。

标签: c++ sse simd intrinsics sse2


【解决方案1】:

您正在尝试模仿这行 HLSL,对吗?

vec2.wxy = vec1.xyz;

您可以通过使用_mm_shuffle_ps 可以以某种有限的方式组合两个向量这一事实来到达某个地方。这是我的尝试:

// xyzw is vec1, XYZW is vec2
__m128 xxZZ = _mm_shuffle_ps(vec1, vec2, _MM_SHUFFLE(2, 2, 0, 0));
__m128 ZxZx = _mm_shuffle_ps(xxZZ, xxZZ, _MM_SHUFFLE(0, 2, 0, 2));
__m128 yzZx = _mm_shuffle_ps(vec1, ZxZx, _MM_SHUFFLE(1, 0, 2, 1));

vec2 = yzZx;

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 2011-04-05
    • 2015-01-26
    • 2021-12-17
    • 2022-10-09
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多