Arm 霓虹灯溢出检测

Arm 霓虹灯溢出检测,arm,overflow,neon,Arm,Overflow,Neon,我有一个长循环,其中霓虹灯矢量加法是在8位元素上执行的。问题是,过了一段时间,几乎可以肯定,由于溢出,部分或所有向量分量都饱和了。有没有一种快速的方法来检测这个,这样我就可以刷新结果,将向量归零,然后继续?我已经试过检查C和V标志,但neon操作似乎没有设置它们 编辑:这里是感兴趣的代码,有点简化。另外,我升级到16位,但它仍然会溢出 int16x8_t Sum; for(int C = 0; C < 100; C++) { // Sum += |a - b| Sum =

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

编辑:这里是感兴趣的代码,有点简化。另外,我升级到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)
    );
}
如果用于求和,它不仅会对值进行饱和钳位,而不是溢出和环绕,这本身可能是可取的,而且每当发生这种情况时,它还会在FPSCR中设置饱和标志位27。设置后,需要通过将位27置零回写FPSCR值来手动清除该标志


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

如果您显示一些代码,以便人们能够准确地了解您的意思,可能会有所帮助。我认为100项计数是一种简化?我看不出16位累积8位值怎么可能溢出,否则65535/255=257>100。此外,vld1q_16uint16_t*a中的指针看起来非常可疑-a是什么类型?如果它仍然是一个8位数据的数组,那么这个代码就完全被破坏了。a是16位,但它是有符号的,现在我使用vld1q_s16和int16_t*好的,我编辑了这个问题,添加了一些代码。我将进行调查,以检查vabaq是否使用vqadd来累积结果。如果没有,我可能会创建我自己的内在,可能是使用vaba和vqadd,但我仍然需要对此进行一些研究。您仍然可以使用一对vabal内在函数的加宽方法。想想看,这样你就不需要浪费时间检查溢出了——只要在每256次迭代后刷新结果向量,你就可以保证它永远不会发生。