arm 霓虹灯比较操作产生负一

Posted

技术标签:

【中文标题】arm 霓虹灯比较操作产生负一【英文标题】:arm neon compare operations generate negative one 【发布时间】:2016-06-19 12:04:43 【问题描述】:

我正在尝试以下汇编代码:

vclt.f32 q9,q0,#0
vst1.i32 q9,[r2:128]

但如果条件为真,则q9中的对应元素设置为负一而不是正一。

我该怎么做才能得到一个积极的?

【问题讨论】:

它产生所有 1 位,如果您将其解释为 2 的补码符号,它确实是 -1。如果您只需要一个 1 位,您如何使用按位AND 所以这是正常结果?我认为这是一种错误。谢谢 是的,这很正常。这对于掩蔽操作更有用,您也可以轻松地从中获得您想要的。 @PaulR:我倾向于关闭那个作为此副本的副本。这个有更实际的答案,谈论你可以用 -1 做什么,因为问题是“我如何使用这个”,而不是“为什么?”。特别是 Notlikethat 的答案有实际的指令名称(与我的答案中的挥手相比:P) @PeterCordes:是的,我认为你是对的 - 我现在已经将欺骗锤应用于较旧的问题,并撤回了对这个问题的近距离投票。 【参考方案1】:

NEON 中没有很多条件性的东西,但实际上只能使用按位而不是布尔逻辑 - 参见例如vbsl.

如果你对 BASIC 有可怕的记忆并且真的讨厌按位真值,那么将掩码转换为布尔值的简单方法就是只取每个元素的最高位:

vshr.u32 q9, q9, #31

虽然否定,虽然可以说一目了然不太清楚,但在某些情况下可能在微观上表现得更好:

vneg.s32 q9, q9

(通过浏览微架构时序,这两个操作几乎相同,但vneg 相对于vshr 的一些理论上的优势是它稍后会在 Cortex-A8 上消耗其输入,并且可以发出两个 ASIMD 管道Cortex-A57/A72)

无论哪种方式,如顶部所述,只有将结果存储回内存以供非向量化代码查看时才真正有意义。

【讨论】:

微架构信息记录在哪里? ARM 有没有像 Agner Fog's x86 microarch guide and instruction timings 这样的东西,其中时序以易于翻转的格式列出?一个快速的谷歌找到了this official ARM page,但我总是发现 ARM 的官方网站很难导航,尤其是。用于比较不同 ARM 版本之间的内容。 (从不同的*** ARM 芯片向下导航同一棵树是荒谬的。) @Peter 较旧的内核(最高 Cortex-A9)在其 TRM 中提供了一般的周期时序,如您所见,最新的内核开始公开发布 optimisation guides;遗憾的是中间有一点空隙。我遇到的唯一一点 Agner 风格的逆向工程是 this partial analysis of Cortex-A7。【参考方案2】:

这对于向量比较指令是正常的,因此您可以将比较结果用作带有 AND 或 XOR 指令或各种其他用例的掩码。

您通常不需要 +1。例如,如果要计算匹配的元素个数,只需使用减法指令从向量累加器中减去 0 或 -1。


要得到一个整数 +1,你可以从 0 中减去它,或者右移元素大小 -1。 (例如,逻辑右移 31 只留下低位 0 或 1,其余位全为零)。您还可以使用您之前创建的 +1 向量进行 AND。

我不知道其中哪一个最适合 ARM,或者这是否取决于微架构。 (我真的只知道 x86 SSE/AVX 的 SIMD。)不过,我确信 NEON 至少可以完成我所描述的选项之一。

【讨论】:

C/C++ 中的条件返回 1 但 SIMD 条件返回 -1 很不方便。我制作了一个应用程序,用户可以在其中实时选择向量大小(只是为了显示每个向量的性能)。例如。对于浮动,大小可以是1,4,8。我使用了 Agner 的 VCL。但我必须为向量大小 = 1(即标量)制作特殊模板。我想标量代码和向量代码无论如何都需要不同才能公平地比较性能。

以上是关于arm 霓虹灯比较操作产生负一的主要内容,如果未能解决你的问题,请参考以下文章

ARM中乘法和存储的霓虹灯优化

我们还需要在运行时使用新的 abi arm64-v8a 检测对霓虹灯的支持吗?

RISC V的任何霓虹灯等效物?

影响标志的霓虹汇编向量指令

为 iOS 编译半浮动霓虹灯指令

霓虹灯和手臂组装优化