如何在 Neon 内在函数中使用 if 条件进行并行操作?
Posted
技术标签:
【中文标题】如何在 Neon 内在函数中使用 if 条件进行并行操作?【英文标题】:How to do parallel operation with if condition in Neon intrinsics? 【发布时间】:2013-12-09 03:27:14 【问题描述】:我问了一个关于 vclt_s8 比较的问题。 Does anybody know how to use Neon intrinsics uint8x8_t vclt_s8 (int8x8_t, int8x8_t)
但是,如果我们有这样的代码:
if(a > b + c)
a = b + c;
else if(a < b - c)
a = b - c;
如何将其转换为 Neon 内在函数?在这种情况下,我们似乎无法进行 8 个算子并行操作。不是吗?
【问题讨论】:
【参考方案1】:显然你不能使用 SIMD 进行分支,所以你必须看看如何使用掩码以无分支的方式实现这种逻辑。我只是给出伪代码,所以你会明白一般的想法 - 编码应该相当简单:
bc = b + c ; get `(b + c)` in a vector register
mask = a > bc ; use compare instruction to generate mask (-1 = true, 0 = false)
bc = bc & mask ; use bitwise AND to zero out elements of `(b + c)` which we do not want
a = a & ~mask ; use bitwise ANDC to zero out elements of `a` which we do not want
a = a | bc ; combine required elements into `a` using bitwise OR
bc = b - c ; get `(b - c)` in a vector register
mask = a < bc ; use compare instruction to generate mask (-1 = true, 0 = false)
bc = bc & mask ; use bitwise AND to zero out elements of `(b - c)` which we do not want
a = a & ~mask ; use bitwise ANDC to zero out elements of `a` which we do not want
a = a | bc ; combine required elements into `a` using bitwise OR
请注意,我在这里作弊并从您的标量代码中省略了else
(假设这两个分支是互斥的)所以我实现的实际上相当于:
if (a > b + c)
a = b + c;
if (a < b - c)
a = b - c;
如果这是一个错误的假设,那么您将需要执行一些额外的按位运算来实现逻辑 else
。
【讨论】:
让 a = 2, b = 2, c = -1... 你需要正确处理它! (OP 使用的是 's8' 内在函数,所以我猜签名对他们很重要) @James:不一定——这取决于用例——从图像/信号处理的上下文来看,我的猜测是c
总是积极的——如果不是这样,但它很容易添加更多按位指令来实现else
,正如我上面所说的,但你不想这样做并在不需要时牺牲性能。
掩码是签名还是未签名? int8x8_t 掩码;或 uint8x8_t 掩码;
@BonderWu:这真的没关系 - 每个元素都是 1 表示“真”(将其视为 255 或 -1,无论你喜欢哪个),而全 0 表示“假”。请参阅您的previous question 接受的答案,他们使用无符号掩码结果。
@BonderWu:如果这有助于您解决问题,请接受答案以上是关于如何在 Neon 内在函数中使用 if 条件进行并行操作?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ARM NEON 内在函数将 u8 掩码转换为 u32 掩码?