【问题标题】:Invert a (small) permutation反转(小)排列
【发布时间】:2015-04-01 10:46:42
【问题描述】:

我正在使用 OpenCL 的 shuffle 函数对 float3 向量进行排序,如下所示(忽略实际 4d 向量的最后一个分量):

uint4 mask = (uint4)(0,1,2,3);
mask.xyz = res.x < res.y ? (res.x >= res.z ? mask.yxz : mask.yzx) : (res.y >= res.z ? mask.xyz : mask.xzy);
float4 abcd = shuffle(res,mask);

然后我对向量abcd的每个分量进行操作,并想反转排序排列,如下:

uint4 inv_mask = ... // ???
res = shuffle(abcd,inv_mask); // Inverse the sorting permutation

如何有效地计算逆掩码?

【问题讨论】:

    标签: bit-manipulation opencl intrinsics


    【解决方案1】:

    可能性的数量非常有限:

    1. x >= y >= z => mask.xyz = (0,1,2), inv_mask = (0,1,2)
    2. x >= z >= y => mask.xyz = (0,2,1), inv_mask = (0,2,1)
    3. y >= x >= z => mask.xyz = (1,0,2), inv_mask = (1,0,2)
    4. y >= z >= x => mask.xyz = (1,2,0), inv_mask = (2,0,1)
    5. z >= x >= y => mask.xyz = (2,0,1), inv_mask = (1,2,0)
    6. z >= y >= x => mask.xyz = (2,1,0), inv_mask = (2,1,0)

    请注意,六种可能的排列中只有两种包含不止一个交换,因此其余 4 种排列会自行反转。

    计算出mask后,可以使用以下代码得到inv_mask

    inv_mask.xyz = mask.xyz == (int3)(1,2,0) ? (int3)(2,0,1) : (mask.xyz == (int3)(2,0,1) ? (int3)(1,2,0) : mask.xyz);

    【讨论】:

      【解决方案2】:

      你是说 uint4 invmask = (uint4)(3,3,3,3) - mask; ?

      对于掩码 (0,3,1,2),这给您 (3-0, 3-3, 3-1, 3-2) = (3,0,2,1)

      【讨论】:

      • 不,这不会给出逆排列(例如,不应更改身份排列掩码的倒数,0,1,2,3)。
      • 这听起来像你有一个置换矩阵(如果元素 i 位于位置 j,则在 (i,j) 处由 1 组成,否则为 0),并且你的倒置排列应该是倒置矩阵。
      • 对。但是对矩阵求逆太大了。
      • 我完全同意。另一种选择可能是事先(在 CPU 上)预先计算 24 个(?)排列,并将它们作为常量、全局浮点数组传输。从内存的角度来看,这不是很大的开销。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      相关资源
      最近更新 更多