【发布时间】:2021-11-04 12:15:16
【问题描述】:
我最近编写了一个在 Arm64 汇编中进行浮点计算的程序。 由于我处理的数字可能会变得非常小,所以我现在想优化代码,使其尽可能地使用精度。
我发现 NEON 引擎有 128 位浮点寄存器,而不是我目前使用的 64 位,所以我寻找了一种使用这些进行计算的方法。我看过的每个网站都告诉我这应该是可能的,但是当我尝试做类似的事情时
fmul v0, v1, v2
我只是得到“错误:指令操作数无效”。
我正在使用应该能够处理 NEON 指令的 M1 芯片,当我将其更改为
fmul v0.2d, v1.2d, v2.2d
完全没有问题。
有人知道我做错了什么吗?还是不能一次使用这些寄存器的所有 128 位?
【问题讨论】:
-
128 位
v寄存器的想法是同时操作两个 64 位双精度值,这就是fmul v0.2d, v1.2d, v2.2d所做的。或四个 32 位值等。这就是 SIMD:单指令多数据。它与您之前的浮点类型和操作相同,只是一次操作更多。当然,您一次可以加载和存储 128 位,但算术都是在多个较小尺寸的元素上进行的。没有 128 位算术。 -
对于答案中的评论所指示的分形,至少对于 Mandelbrot/Julia,最好的办法是使用可以保持 4.0 或从 (xx + yy) >= 4.0 可以检测到;记住对 bignum 乘法和复数乘法都使用 Karatsuba 乘法(使用 5 个元素加法和 3 个元素明智乘法,而不是标准的 2+4)。