Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 当有负数时,我的计算结果不正确_Assembly_Arm_Neon_Alphablending - Fatal编程技术网

Assembly 当有负数时,我的计算结果不正确

Assembly 当有负数时,我的计算结果不正确,assembly,arm,neon,alphablending,Assembly,Arm,Neon,Alphablending,我试图使用neon在汇编((200*(53-255))/255)+255中计算以下内容,其结果应等于大约97 我在这里测试过,也在双核Cortex-A7 ARM CPU平板电脑上测试过。结果是243,这是不正确的。 我应该如何实现这一点以获得97的正确结果 d2包含200200 d4包含255255 d6包含53,53,53,53,53,53,53,53,53 vsub.s8 d8, d6, d4 (53 - 255 results in d8 = 54,54,54,54,54,54,54,5

我试图使用neon在汇编((200*(53-255))/255)+255中计算以下内容,其结果应等于大约97

我在这里测试过,也在双核Cortex-A7 ARM CPU平板电脑上测试过。结果是243,这是不正确的。
我应该如何实现这一点以获得97的正确结果

d2包含200200
d4包含255255
d6包含53,53,53,53,53,53,53,53,53

vsub.s8 d8, d6, d4  (53 - 255 results in d8 = 54,54,54,54,54,54,54,54)
vmull.s8 q5,d8,d2  (54 * 200 results in q5 = 244,48,244,48,244,48,244,48,244,48,244,48,244,48,244,48)
vshrn.s16 d12, q5, #8 (divide by 255 results in d12 = 244,244,244,244,244,244,244,244) 
vadd.s8 d5, d4, d12  (final result d5 = 243,243,243,243,243,243,243,243) 

243是绝对正确的

alpha通道是一个无符号的8位值,您应该使用
u8
u16
而不是
s8
s16

而对于位宽保持不变的标准算术,符号并不重要,对于乘法长来说,情况完全不同

这就是为什么ARM
UMULL
SMULL
有两条单独的指令用于长乘法,而单个
MUL
指令用于32位有符号和无符号乘法

54*200根本不可能,因为200在有符号乘法中被解释为-56

=>
54*-56 = -3024
-3024/256 = -12
-12 + -1 = -13    // 255 = -1
-13 = 243
实际上,您必须将
vmull.s8
更改为
vmull.u8

=>
54*200 = 4800
2800/256 = 18
18 + -1 = 17
老实说,我不知道你怎么期望上面的ops的结果是97:它怎么会像一个标签所暗示的那样是某种阿尔法混合呢

此外,
>8
不是
/255
。这只是一个糟糕的近似值。你可能会认为你可以生活在如此低的精度下,但当alpha混合时,这远远不够


你一定是做错了什么。

我在neon asm中尝试实现的alpha混合公式是output_red=((alpha_front*(red_front-red_bak))/255)+red_bak,并对蓝色和绿色像素重复。我希望当红色锋=53,红色锋=255,阿尔法锋=200时,结果是97。通过计算器:53-255=-202,-202 x 200=-40400,-40400/255=-158,最后是-158+255=97。我已经尝试过vmull.u8,结果是41。关于右移或除以255,这里有一些使用它的参考,这是错误的。正确的公式是:rslt=(阿尔法*正面+(255阿尔法)*背面)/255.(200*53+55*255)/255=96。给定值的正确结果是96,97,带圆纹,我从研究中了解到,alpha混合有许多不同的公式。我实际上实现了我在python问题中列出的公式((alpha*(front-back))/255)+back,它在@Jake中运行得非常好。我希望我能把它的截图发给你,因为它看起来非常好。但是,实现非常慢,因为它是用python实现的。我现在试图在neon asm中实现这一点。您使用的公式忽略了两件事:1)它试图减少乘法运算,希望更快。但是现在像ARM这样的现代杯子有非常快速的乘法运算指令。因此,它的作用恰恰相反。2) 它需要寄存器的全位宽度。这根本不适用于SIMD,因为在SIMD中,节省位可以极大地提高性能。=>你应该用我给霓虹灯的公式。