NEON 溢出检测

Posted

技术标签:

【中文标题】NEON 溢出检测【英文标题】:NEON Overflow detection 【发布时间】:2015-08-27 23:16:11 【问题描述】:

我有一个长循环,其中对 8 位元素执行霓虹矢量加法。问题是一段时间后,几乎可以肯定部分或全部向量分量由于溢出而饱和。有没有一种快速的方法来检测这一点,以便我可以刷新结果,将向量归零并继续?我已经尝试过检查 C 和 V 标志,但似乎霓虹灯操作没有设置它们。

编辑:这里是感兴趣的代码,稍微简化了一点。还有,我升级到16位了,还是会溢出

int16x8_t Sum;
for(int C = 0; C < 100; C++)

    // Sum += |a - b|
    Sum = vabaq_u16(
      Sum,                      
      vld1q_u16((uint16_t *)a),
      vld1q_u16((uint16_t *)b)
    );

【问题讨论】:

如果您显示一些代码可能会有所帮助,以便人们可以准确地看到您的意思 我认为 100 项目数之一是简化?我看不出你怎么可能溢出 16 位,否则累积 8 位值(65535 / 255 = 257 > 100)。 另外,vld1q_u16((uint16_t *)a) 中的指针看起来很可疑 - a 是什么类型?如果它仍然是一个 8 位数据的数组,那么这段代码就完全被破坏了。 是的,这是一个简化,是的,a 有问题。 a 是 16 位的,但它是有符号的,现在我使用的是 vld1q_s16 和 (int16_t*) 【参考方案1】:

如果您使用VQADD 进行求和,它不仅会使值饱和(钳位)而不是溢出和回绕(这本身可能是可取的),而且还会设置饱和标志(位 27)每当发生这种情况时,都在 FPSCR 中。设置后,需要手动清除该标志,方法是写回第 27 位为零的 FPSCR 值。

一种可能的替代方法,具体取决于算法的其余部分如何使用结果,可能是将累加器拆分为两个寄存器,并对输入向量的每一半使用扩展操作 (VABAL) 来累加 16-位元素,那么您可以简单地以预定时间间隔刷新结果,而无需显式检查。由于溢出 16 位累加器所需的无符号 8 位值的最小数量为 258(65535/255 = 257),因此如果循环每 257 次或更少的迭代刷新一次结果,则溢出是不可能的。

【讨论】:

好的,我编辑了问题,添加了一些代码。我将调查检查 vabaq 是否使用 vqadd 来累积结果。如果没有,我可能会创建自己的内在函数,可能使用 vaba 和 vqadd,但我仍然需要对其进行一些研究。 您仍然可以使用扩展方法和一对vabal 内在函数。想一想,这样您实际上就不需要浪费时间检查溢出 - 只需在大约每 256 次迭代后刷新结果向量,您就可以保证它永远不会发生。

以上是关于NEON 溢出检测的主要内容,如果未能解决你的问题,请参考以下文章

系统在此应用程序中检测到基于堆栈的缓冲区溢出。溢出...

溢出漏洞利用原理及其检测原理——就是代码注入shellcode,检测可以利用静态签名

FreeRTOS操作系统例程:任务栈溢出检测

定点数运算及溢出检测

如何检测角度控制器中的文本是不是溢出(文本溢出:省略号)

缓存区溢出检测工具BED