Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.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
Arm 如何使用neon创建1/255 f32矢量?_Arm_Neon - Fatal编程技术网

Arm 如何使用neon创建1/255 f32矢量?

Arm 如何使用neon创建1/255 f32矢量?,arm,neon,Arm,Neon,当我计算alpha混合时,我需要将8bit alpha转换为float,即alpha/255。因为霓虹灯没有除法,所以我想要alpha*1/255。那么如何在q1中生成1/255向量呢 vmov.f32 q1,#0.003921569始终报告错误 vmov.u32 q1#255 vrecpe.u32 q1,q1在f32中始终生成0。不是100%的答案,但由于到目前为止您还没有得到任何其他答案,我想我可以帮助您开始 根据我的记忆,可以使用vmov.f32加载的浮点子集非常有限,因此如果要加载任意浮

当我计算alpha混合时,我需要将8bit alpha转换为float,即alpha/255。因为霓虹灯没有除法,所以我想要alpha*1/255。那么如何在q1中生成1/255向量呢

vmov.f32 q1,#0.003921569始终报告错误

vmov.u32 q1#255
vrecpe.u32 q1,q1在f32中始终生成0。

不是100%的答案,但由于到目前为止您还没有得到任何其他答案,我想我可以帮助您开始

根据我的记忆,可以使用
vmov.f32
加载的浮点子集非常有限,因此如果要加载任意浮点,需要将其存储为常量,并使用
vldr
从常量池加载。像这样的事情应该可以做到

ldr r1,=floats 

vldr.32 s0,[r1]     @1/256

floats:
.float 0.003921569

“非100%”部分是因为我没有查看向量指令,所以我不确定您是否可以立即用此代码中的
q1
替换
s0
,或者是否需要在加载后将
s0
移动到
q1

不是100%答案,但既然你还没有找到其他人,我想我会帮你开始

根据我的记忆,可以使用
vmov.f32
加载的浮点子集非常有限,因此如果要加载任意浮点,需要将其存储为常量,并使用
vldr
从常量池加载。像这样的事情应该可以做到

ldr r1,=floats 

vldr.32 s0,[r1]     @1/256

floats:
.float 0.003921569

“非100%”部分是因为我没有研究向量指令,所以我不确定您是否可以立即用此代码中的
q1
替换
s0
,或者是否需要在加载后将
s0
移动到
q1

您很接近了。在取倒数之前,需要将255的向量转换为浮点

vmov.u32        q0, #255
vcvt.f32.u32    q0, q0
vrecpe.f32      q1, q0

请注意,
vrecpe
有少量错误,但应该足够接近alpha混合。

您已经接近了。在取倒数之前,需要将255的向量转换为浮点

vmov.u32        q0, #255
vcvt.f32.u32    q0, q0
vrecpe.f32      q1, q0
请注意,
vrecpe
有少量错误,但它应该足够接近alpha混合。

可能是您想要的 float32x4_t x=vdupq_n_32(1.0f/255)

编译器负责计算常量,vdup指令将值广播到向量的所有四个通道

vdup指令支持霓虹灯标量和ARM寄存器作为源操作数 float32x4_t x=vdupq_n_32(1.0f/255)

编译器负责计算常量,vdup指令将值广播到向量的所有四个通道


vdup指令支持霓虹灯标量和ARM寄存器作为源操作数

对于一个简单的alpha混合,您真的不必为浮点而烦恼。鉴于:

y = rint(x * a / 255.0);
对于任何8位输入,您可以使用以下方法获得相同的结果,而无需使用浮点:

t = x * a;
t += (t + 0x80) >> 8;
y = (t + 0x80) >> 8;
这有点像:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    vrsra.u16 q2, q2, #8
    vrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2
通常,最后两个操作实现从16位输入到8位输出的整数除以255;但它们依赖于8乘8的有限范围。如果16位中间值不仅仅是乘法的结果,那么可能需要钳制,并且由于没有
vqrsra
序列,因此序列变长:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    ???
    vrshr.u16 q3, q2, #8
    vqadd.u16 q2, q2, q3
    vqrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2

对于一个简单的alpha混合,您真的不必为浮点而烦恼。鉴于:

y = rint(x * a / 255.0);
对于任何8位输入,您可以使用以下方法获得相同的结果,而无需使用浮点:

t = x * a;
t += (t + 0x80) >> 8;
y = (t + 0x80) >> 8;
这有点像:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    vrsra.u16 q2, q2, #8
    vrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2
通常,最后两个操作实现从16位输入到8位输出的整数除以255;但它们依赖于8乘8的有限范围。如果16位中间值不仅仅是乘法的结果,那么可能需要钳制,并且由于没有
vqrsra
序列,因此序列变长:

; given eight 8-bit x in d0, and eight 8-bit a in d1
    vmull.u8 q2, d0, d1
    ???
    vrshr.u16 q3, q2, #8
    vqadd.u16 q2, q2, q3
    vqrshrn.u16 d2, q2, #8
; result is eight 8-bit (s*a/255) in d2

谢谢你的回答!是的,neon也可以加载常量。asm代码嵌入在C中,因此我也可以在C中计算浮点常量。但是neon不能像r0那样移动寄存器到Q0/S0,对吗?也许我必须将常量传递给变量,并将变量地址传递给嵌入的asm代码。@RichardZhao:当然,您可以从r0移动到s0<代码>vmov s0,r0。您还可以将预计算的常数直接加载到
s0
q0
,这可能是您实际需要的。谢谢您的回答!是的,neon也可以加载常量。asm代码嵌入在C中,因此我也可以在C中计算浮点常量。但是neon不能像r0那样移动寄存器到Q0/S0,对吗?也许我必须将常量传递给变量,并将变量地址传递给嵌入的asm代码。@RichardZhao:当然,您可以从r0移动到s0<代码>vmov s0,r0。您还可以将预计算的常量直接加载到
s0
q0
,这可能是您实际需要的;使用16位定点算法可以获得足够的精度,这样可以在每个向量中保留更多的像素;您可以使用16位定点算法获得足够的精度,该算法允许在每个向量中保留更多像素。