armv8-a:测试 SIMD 寄存器是不是为 != 0

Posted

技术标签:

【中文标题】armv8-a:测试 SIMD 寄存器是不是为 != 0【英文标题】:armv8-a: test if SIMD register is != 0armv8-a:测试 SIMD 寄存器是否为 != 0 【发布时间】:2017-03-24 20:54:07 【问题描述】:

这是一个与one非常相似的问题。

在 armv7-a 上,我有以下汇编代码:

vcmp.f64 d0, #0
vmrs APSR_nzcv, fpscr
beq .jumpover

如何将此代码转换为 armv8-a?我想测试v0.16b中是否有非零像素。

编辑#1

我在想这样的事情:

addv b0, v0.16b
fcmp s0, #0.0
beq .jumpover

这是正确的吗?另外,我阅读了以下语句“浮点FCMP和FCCMP指令直接设置整数条件标志,不要修改FPSR中的条件标志。”我不能 100% 理解。

【问题讨论】:

请参阅element14.com/community/servlet/JiveServlet/previewBody/…。就像你想要数据移动指令一样。你可以 umov w2,v0.8b[1] 然后 cmp w2, #0 您的问题没有意义,因为您是在以整数数据格式描述数据,但要谈谈执行浮点比较。 ADDV d, Vn. 整数和元素到标量(向量)。其中 / 是 B/8B、B/16B、H/4H、H/8H、S/2S 或 S/4S。 @Ross Ridge,我的代码适用于 armv7-a。我将 8 个字节加载到 d0 中,然后将向量作为浮点数(64 位)进行比较。阅读 armv7-a 规范。 这肯定只是mov x0, v0.d[0] ; cmp x0, #0 ; beq .jumpover 【参考方案1】:

在 cmets 中的 sh1 找到了一个可行的解决方案:

mov x0, v0.d[0]
cmp x0, #0
beq .jumpover

mov x0, v0.d[1]
cmp x0, #0
beq .jumpover

您必须对 d[0] 和 d[1] 都执行此操作才能检查 16 个像素。

【讨论】:

是的 - 这很有道理!【参考方案2】:

需要检查 smov w1, v1.h[0] 的周期;这是单个 SIMD 元素移动到通用寄存器。

    data                                                                                                                                                                   
array:  .byte 0,0,0,0,0,0,1,0                                                                                      
    .text                                                                                                                                                                   
            .global main                                                                                                                                                    

    main:                                                                                                                                                                   
            ldr x20,=array                  // array pointer                                                                                                                
            ld1 v0.8b, [x20]              // just for eg.,                                                                                                  
            cmgt v1.8b, v0.8b, #0           // any non-zero values ?                                                                                                        
            addv b1, v1.8b                  // vector reduce across lanes - element 0 in all sizes will hold some value :: conjecture                                       
            smov w1, v1.h[0]                // sign or unsigned - don't matter - index 0 will have some value   - check cycles                                              
            cmp w1, #0                      //                                                                                                                              
            cset w1, ne                     // just to test - (branch)  

【讨论】:

感谢您的建议。我在 armv7-a 上做过类似的事情,但我认为它完全没有效率。因为您付出了从 SIMD 数据中提取 8 次的代价,然后每次都进行比较。我不是霓虹灯专家,但有人告诉我它超级贵。 哦,我明白了。是的,在常规寄存器和 SIMD 寄存器之间移动可能会变得昂贵。请查看从第 111 页开始的向量算术部分。有一些向量比较掩码可能是您想要的。我会删除我的答案。

以上是关于armv8-a:测试 SIMD 寄存器是不是为 != 0的主要内容,如果未能解决你的问题,请参考以下文章

[译] ARMv8-A的基础知识

在同一个 SIMD 寄存器中串行添加值

SIMD (AVX2) - 将 uint8_t 值加载到多个浮点 __m256 寄存器

将数据放入 SIMD 寄存器需要多少个周期?

有没有一种有效的方法来使用 SIMD 内在函数来获取 SIMD 寄存器中的第一个非零元素?

可以通过使用输入寄存器来寻址输出 SIMD 寄存器