【问题标题】:comparision with zero using neon instruction使用霓虹灯指令与零进行比较
【发布时间】:2016-04-02 22:29:24
【问题描述】:

我有以下代码

if(value  == 0)
{
    value = 1;
}

使用 NEON 矢量化指令我需要执行上述操作。如何一次将 NEON 寄存器值与 0 进行比较以判断 4 个元素是否相等,如果元素为零,则将值更改为 1。

【问题讨论】:

标签: arm compare simd neon


【解决方案1】:

假设整数数据,那么由于 NEON 具有特定的“与零比较”指令,并且按位方式比较结果有效,因此仅使用一个备用寄存器就可以做到这一点。在广义伪汇编中:

VCEQ.type  mask, data, #0    @ Generate bitmask vector with all bits set in elements
                             @  corresponding to zero elements in the data
VSUB.type  data, data, mask  @ Interpret "mask" as a vector of 0s and -1s, with the
                             @  result of incrementing just the zero elements of "data"
                             @  (thanks to twos complement underflow)

这个技巧不适用于浮点数据,因为非零值的位模式更复杂,如果替换值不是 1(或 -1),它也不起作用,所以在在这些情况下,您需要构建一个包含适当替换元素的单独向量,并根据@Ermlg's answer 使用比较掩码进行条件选择。

【讨论】:

  • 由于 (float)0 的按位表示与 ieee754-floats 中的 (int)0 相同,因此您可以只按位表示掩码,并使用 1( 或其他任何浮点表示您想要将零元素设置为的值),然后添加而不是减去。
  • @EOF ...但是一旦你手头有一个替换值向量,按位-然后相加是两条指令,而对于带有结果掩码的向量的直接条件选择只有一条指令; )
【解决方案2】:

如果你想检查一个向量的 any 元素是否非零并在其上分支:


您可以跨矢量通道使用 get min/max。

if(vmaxvq_u32(value) == 0) { // Max value across quad vector, equals zero?
    value = vmovq_n_u32(1); // Set all lanes to 1
}

对于双向量

if(vmaxv_u32(value) == 0) { // Max value across double vector, equals zero?
    value = vmov_n_u32(1); // Set all lanes to 1
}

请注意,唯一的区别是 'q' 用于指示四 128 位向量或 64 位双向量(如果不是)。编译器将使用 mov 指令从 neon single 转移到 arm 通用寄存器进行比较。

【讨论】:

  • 这个问题不是关于检查 all 元素是否为零,它实际上只是微不足道的如何使用-vceq 来获得 0 / -1 的掩码。这将是对Neon 64 bit aarch: compare vector to zero 的回答。我不确定在任何地方是否有该问题的 32 位 ARM 版本。如果人们在实际寻找您回答的内容时碰巧发现了这个问题(如果向量的 any 元素与条件匹配,则为标量分支),这在这里有点用处。
【解决方案3】:

也许它看起来像这样:

uint32x4_t value = {7, 0, 0, 3};
uint32x4_t zero = {0, 0, 0, 0};
uint32x4_t one = {1, 1, 1, 1};

uint32x4_t mask = vceqq_u32(value, zero);

value = vbslq_u32(mask, one, value);

如需了解更多信息,请参阅here

【讨论】:

  • 我需要上述程序的汇编代码请回复@Ermlg
  • 谢谢@Ermlg,我在汇编中实现了它工作正常
猜你喜欢
  • 1970-01-01
  • 2013-11-07
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 2015-02-14
相关资源
最近更新 更多