平均操作ARM NEON

use*_*328 3 arm sse simd intrinsics neon

我需要计算与SSE相同的操作:

__m128i result1=_mm_avg_epu8 (upper, lower);
Run Code Online (Sandbox Code Playgroud)

使用NEON,我执行以下操作:

uint8x16_t result1=vhaddq_u8(upper, lower);
Run Code Online (Sandbox Code Playgroud)

结果应该是相同的,但我得到的SSE指令:

91cb c895 aaa3 b0d4 cfc0 c1b0 aac7 b9b9
Run Code Online (Sandbox Code Playgroud)

而使用NEON指令我获得:

91ca c894 a9a2 b0d3 cec0 c1af aac7 b8b8 
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这两个结果不同.你能帮助我吗?

Pau*_*l R 5

霓虹灯"减半添加"操作的vhadd工作方式如下:

A = (B + C) >> 1
Run Code Online (Sandbox Code Playgroud)

而SSE平均内在_mm_avg_epu8这样做:

A = (B + C + 1) >> 1
Run Code Online (Sandbox Code Playgroud)

换句话说,Neon 通过"减半添加"操作进行截断平均,而SSE正确地舍入结果.

幸运的是,有一个霓虹灯指令以与SSE相同的方式进行_mm_avg_epu8- 它被称为vrhadd - Vector Rounding Halving Add.


aus*_*len 5

你可以使用vrhadd [1] [2].

Vector rounding halving add: vrhadd -> Vr[i]:=(Va[i]+Vb[i]+1)>>1
Run Code Online (Sandbox Code Playgroud)

  • 许多 NEON 指令具有 Q 和 R 标志,q 表示饱和,r 表示舍入。 (2认同)