Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.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
Optimization ARM霓虹灯组装和浮点舍入_Optimization_Assembly_Arm_Neon - Fatal编程技术网

Optimization ARM霓虹灯组装和浮点舍入

Optimization ARM霓虹灯组装和浮点舍入,optimization,assembly,arm,neon,Optimization,Assembly,Arm,Neon,我正在为使用NEON的ARM处理器进行代码优化。但是我有一个问题:我的算法包含以下浮点计算: round(x*b - y*a) 结果可以是积极的,也可以是消极的 实际上,我使用2个VMUL和1个VSUB来进行并行计算(每个操作4个值,使用Q寄存器和32位浮点) 有办法解决这个问题吗?如果结果都是相同的符号,我知道我可以简单地先加上或减去0.5,NEON会有很长的延迟,尤其是在浮点乘法之后。 与vfp编程相比,使用两个vmul和一个vsub不会获得太多收益 因此,您的代码应该如下所示: vmul

我正在为使用NEON的ARM处理器进行代码优化。但是我有一个问题:我的算法包含以下浮点计算:

round(x*b - y*a)
结果可以是积极的,也可以是消极的

实际上,我使用2个VMUL和1个VSUB来进行并行计算(每个操作4个值,使用Q寄存器和32位浮点)


有办法解决这个问题吗?如果结果都是相同的符号,我知道我可以简单地先加上或减去0.5,NEON会有很长的延迟,尤其是在浮点乘法之后。 与vfp编程相比,使用两个vmul和一个vsub不会获得太多收益

因此,您的代码应该如下所示:

vmul.f32 result, x, b
vmls.f32 result, y, a
这些乘法累积/减法指令与前一条乘法指令背靠背发出,没有任何延迟。(本例中保存了9个循环)

不幸的是,我不理解你的实际问题。为什么有人要对浮点值进行四舍五入?显然,你打算提取整数部分,有几种方法可以做到这一点,我不能告诉你更多,因为你的问题总是太模糊了

我在这个论坛上关注你们的问题已经有相当长的一段时间了,我无法摆脱这样一种感觉:你们缺少一些非常基本的东西


我建议您先阅读ARM上的汇编参考指南pdf。

首先,NEON会有很长的延迟,尤其是在浮点乘法之后。 与vfp编程相比,使用两个vmul和一个vsub不会获得太多收益

因此,您的代码应该如下所示:

vmul.f32 result, x, b
vmls.f32 result, y, a
这些乘法累积/减法指令与前一条乘法指令背靠背发出,没有任何延迟。(本例中保存了9个循环)

不幸的是,我不理解你的实际问题。为什么有人要对浮点值进行四舍五入?显然,你打算提取整数部分,有几种方法可以做到这一点,我不能告诉你更多,因为你的问题总是太模糊了

我在这个论坛上关注你们的问题已经有相当长的一段时间了,我无法摆脱这样一种感觉:你们缺少一些非常基本的东西


我建议您先阅读ARM上的汇编参考指南pdf。

我不懂汇编,但使用C语言中的NEON intrinsic(我提到了它们的汇编等价物以帮助您浏览文档,尽管我自己无法使用它们),用于
round
函数的算法可以是:

// Prepare 3 vectors filled with all 0.5, all -0.5, and all 0
// Corresponding assembly instruction is VDUP
float32x4_t plus  = vdupq_n_f32(0.5);
float32x4_t minus = vdupq_n_f32(-0.5);
float32x4_t zero  = vdupq_n_f32(0);

// Assuming the result of x*a-y*b is stored in the following vector:
float32x4_t xa_yb;

// Compare vector with 0
// Corresponding assembly instruction is VCGT
uint32x4_t more_than_zero = vcgtq_f32(xa_yb, zero);
// Resulting vector will be set to all 1-bits for values where the comparison
// is true, all 0-bits otherwise.

// Use bit select to choose if you have to add or substract 0.5
// Corresponding assembly instruction is VBSL, its syntax is quite alike
// `more_than_zero ? plus : minus`.
float32x4_t to_add = vbslq_f32(more_than_zero, plus, minus);

// Add this vector to the vector to round
// Corresponding assembly instruction is VADD,
// but I guess you knew this one :D
float32x4_t rounded = vaddq_f32(xa_yb, to_add);

// Then cast to integers!
我想您将能够将此转换为汇编(无论如何,我不是)


请注意,我不知道这是否真的比标准代码、非SIMD代码更有效

我没有汇编方面的知识,但是使用C语言中的NEON intrinsic(我提到它们的汇编等价物是为了帮助您浏览文档,尽管我自己无法使用它们),用于
round
函数的算法可以是:

// Prepare 3 vectors filled with all 0.5, all -0.5, and all 0
// Corresponding assembly instruction is VDUP
float32x4_t plus  = vdupq_n_f32(0.5);
float32x4_t minus = vdupq_n_f32(-0.5);
float32x4_t zero  = vdupq_n_f32(0);

// Assuming the result of x*a-y*b is stored in the following vector:
float32x4_t xa_yb;

// Compare vector with 0
// Corresponding assembly instruction is VCGT
uint32x4_t more_than_zero = vcgtq_f32(xa_yb, zero);
// Resulting vector will be set to all 1-bits for values where the comparison
// is true, all 0-bits otherwise.

// Use bit select to choose if you have to add or substract 0.5
// Corresponding assembly instruction is VBSL, its syntax is quite alike
// `more_than_zero ? plus : minus`.
float32x4_t to_add = vbslq_f32(more_than_zero, plus, minus);

// Add this vector to the vector to round
// Corresponding assembly instruction is VADD,
// but I guess you knew this one :D
float32x4_t rounded = vaddq_f32(xa_yb, to_add);

// Then cast to integers!
我想您将能够将此转换为汇编(无论如何,我不是)


请注意,我不知道这是否真的比标准代码、非SIMD代码更有效

您好,是的,我需要提取整数部分。谢谢你的建议,我会尽快阅读参考指南,我也在关注你的博客,非常有趣。这样你就不必用浮点格式进行取整了。只需使用vcvt.s32.f32将float转换为1个分数位的int,然后就可以使用vrshr.s32进行舍入。这就是我所说的“对你的问题更加具体”的意思,我错过了VCVT指令中的#fbits可选值。我已经测试过你的解决方案:对于正值,它是可以的,但是负值没有正确舍入,-0.9舍入为0,而不是-1。哦,我明白了。那么这应该可以工作了:vshr.u32 temp,result,#31;veor.32结果,温度;vrshr.s32结果,#1直到负数出现错误-0.1至-0.9正常(0和-1),-1至-1.4错误(=0),-1.5至-1.9正常(=2),-2至-2.4错误(=1),-2.5至-2.9正常(=3)。。。等谢谢你的耐心。你好,是的,我需要提取整数部分取整。谢谢你的建议,我会尽快阅读参考指南,我也在关注你的博客,非常有趣。这样你就不必用浮点格式进行取整了。只需使用vcvt.s32.f32将float转换为1个分数位的int,然后就可以使用vrshr.s32进行舍入。这就是我所说的“对你的问题更加具体”的意思,我错过了VCVT指令中的#fbits可选值。我已经测试过你的解决方案:对于正值,它是可以的,但是负值没有正确舍入,-0.9舍入为0,而不是-1。哦,我明白了。那么这应该可以工作了:vshr.u32 temp,result,#31;veor.32结果,温度;vrshr.s32结果,#1直到负数出现错误-0.1至-0.9正常(0和-1),-1至-1.4错误(=0),-1.5至-1.9正常(=2),-2至-2.4错误(=1),-2.5至-2.9正常(=3)。。。等谢谢你的耐心。