gpt4 book ai didi

c++ - 如何清除 NEON 中除第一个非零车道外的所有车道?

转载 作者:行者123 更新时间:2023-11-30 02:19:07 26 4
gpt4 key购买 nike

我在 uint32x4_t NEON 寄存器中有一个掩码。在此掩码中,至少设置了 4 个整数中的 1 个(例如 0xffffffff),但是,我可能会遇到寄存器中设置了多个项目的情况。如何确保只设置一个?

C伪代码:

uint32x4_t clearmask(uint32x4_t m)
{
if (m[0]) { m[1] = m[2] = m[3] = 0; }
else if (m[1]) { m[2] = m[3] = 0; }
else if (m[2]) { m[3] = 0; }
return m;
}

基本上我想清除除了一条设定车道以外的所有车道。明显straightforward implementation in neon可能是:

uint32x4_t cleanmask(uint32x4_t m)
{
uint32x4_t mx;
mx = vdupq_lane_u32(vget_low_u32(vmvnq_u32(m)), 0);
mx = vsetq_lane_u32(0xffffffff, mx, 0);
m = vandq_u32(m, mx);

mx = vdupq_lane_u32(vget_low_u32(vmvnq_u32(m)), 1);
mx = vsetq_lane_u32(0xffffffff, mx, 1);
m = vandq_u32(m, mx);

mx = vdupq_lane_u32(vget_high_u32(vmvnq_u32(m)), 0);
mx = vsetq_lane_u32(0xffffffff, mx, 2);
m = vandq_u32(m, mx);

return m;
}

如何在 arm neon 中更有效地完成这项工作?

最佳答案

Very simple :

vceq.u32    q1, q0, #0
vmov.i8 d7, #0xff
vext.8 q2, q3, q1, #12

vand q0, q0, q2
vand d1, d1, d2
vand d1, d1, d4

总共 6 条指令,如果您可以将 q3 保持为常数,则为 5 条。

下面的aarch64版本一定更容易理解:

cmeq    v1.4s, v0.4s, #0
movi v31.16b, #0xff

ext v2.16b, v31.16b, v1.16b, #12
ext v3.16b, v31.16b, v1.16b, #8
ext v4.16b, v31.16b, v1.16b, #4

and v0.16b, v0.16b, v2.16b
and v0.16b, v0.16b, v3.16b
and v0.16b, v0.16b, v4.16b

这是如何运作的

ext/vext从两个 vector 的串联中获取一个窗口,因此我们正在创建掩码

v0 = [  d   c   b   a ]

v2 = [ !c !b !a -1 ]
v3 = [ !b !a -1 -1 ]
v4 = [ !a -1 -1 -1 ]

如果前面的任何元素不为零,则最高元素 (d) 归零。

如果其前面的任何元素(ab)非零,则第二高的元素 (c) 被置零。等等。


在保证元素为 0 或 -1 的情况下,mvn 也可以代替与零进行比较。

关于c++ - 如何清除 NEON 中除第一个非零车道外的所有车道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51229457/

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