ARM NEON实现中的Karatsuba算法似乎有错误
我在互联网上找到了许多相同的ARM NEON Karatsuba算法实现的副本,包括一些科学论文,例如 看起来所有这些副本都有相同的问题。虽然说它做算术乘法,但结果仍然是多项式。如果将ARM NEON实现中的Karatsuba算法似乎有错误,arm,multiplication,neon,karatsuba,Arm,Multiplication,Neon,Karatsuba,我在互联网上找到了许多相同的ARM NEON Karatsuba算法实现的副本,包括一些科学论文,例如 看起来所有这些副本都有相同的问题。虽然说它做算术乘法,但结果仍然是多项式。如果将vmull.p8更改为vmull.u8,它将为最小一个字的小数字生成正确的结果。但超过最低单词的大数字是不正确的。 实施看起来不错: .macro mul64_p8 rq rl rh ad bd k16 k32 k48 t0q t0l t0h t1q t1l t1h t2q t2l t2h t3q t3l t3h
vmull.p8
更改为vmull.u8
,它将为最小一个字的小数字生成正确的结果。但超过最低单词的大数字是不正确的。
实施看起来不错:
.macro mul64_p8 rq rl rh ad bd k16 k32 k48 t0q t0l t0h t1q t1l t1h t2q t2l t2h t3q t3l t3h
@A1
vext.8 \t0l, \ad, \ad, $1
@F = A1*B
vmull.p8 \t0q, \t0l, \bd
@B1
vext.8 \rl, \bd, \bd, $1
@E = A*B1 (7)
vmull.p8 \rq, \ad, \rl
@A2
vext.8 \t1l, \ad, \ad, $2
@H = A2*B
vmull.p8 \t1q, \t1l, \bd
@B2
vext.8 \t3l, \bd, \bd, $2
@G = A*B2
vmull.p8 \t3q, \ad, \t3l
@A3
vext.8 \t2l, \ad, \ad, $3
@J = A3*B
vmull.p8 \t2q, \t2l, \bd
@L = E + F
veor \t0q, \t0q, \rq
@B3
vext.8 \rl, \bd, \bd, $3
@I = A*B3
vmull.p8 \rq, \ad, \rl
@M = G + H
veor \t1q, \t1q, \t3q
@B4
vext.8 \t3l, \bd, \bd, $4
@K = A*B4
vmull.p8 \t3q, \ad, \t3l
@t0 = (L) (P0 + P1) << 8
veor \t0l, \t0l, \t0h
vand \t0h, \t0h, \k48
@t1 = (M) (P2 + P3) << 16
veor \t1l, \t1l, \t1h
vand \t1h, \t1h, \k32
@N = I + J
veor \t2q, \t2q, \rq
veor \t0l, \t0l, \t0h
veor \t1l, \t1l, \t1h
@t2 = (N) (P4 + P5) << 24
veor \t2l, \t2l, \t2h
vand \t2h, \t2h, \k16
@t3 = (K) (P6 + P7) << 32
veor \t3l, \t3l, \t3h
vmov.i64 \t3h, $0
vext.8 \t0q, \t0q, \t0q, $15
veor \t2l, \t2l, \t2h
vext.8 \t1q, \t1q, \t1q, $14
vmull.p8 \rq, \ad, \bd
vext.8 \t2q, \t2q, \t2q, $13
vext.8 \t3q, \t3q, \t3q, $12
veor \t0q, \t0q, \t1q
veor \t2q, \t2q, \t3q
veor \rq, \rq, \t0q
veor \rq, \rq, \t2q
.endm
.macro mul64_p8 rq rl右侧ad bd k16 k32 k48 t0q t0l t0h t1q t1l t1h t2q t2l t2h t3q t3l t3h
@A1
vext.8\t0l\ad\ad$1
@F=A1*B
vmull.p8\t0q\t0l\bd
@B1
vext.8\rl\bd\bd$1
@E=A*B1(7)
vmull.p8\rq\ad\rl
@A2
vext.8\t1l\ad\ad$2
@H=A2*B
vmull.p8\t1q\t1l\bd
@B2
vext.8\t3l\bd\bd$2
@G=A*B2
vmull.p8\t3q\ad\t3l
@A3
vext.8\t2l\ad\ad$3
@J=A3*B
vmull.p8\t2q\t2l\bd
@L=E+F
veor\t0q\t0q\rq
@B3
vext.8\rl\bd\bd$3
@I=A*B3
vmull.p8\rq\ad\rl
@M=G+H
veor\t1q\t1q\t3q
@B4
vext.8\t3l\bd\bd$4
@K=A*B4
vmull.p8\t3q\ad\t3l
@t0=(L)(P0+P1)我“不”知道所展示的代码正在尝试做什么(可能成功)。它看起来当然不是64x64=128。从VMULL.U32
开始,只需执行“长乘法”:在操作数如此小(支持的因子长度的两倍)的情况下,单靠进位处理将消除需要较少乘法的任何优势。(甚至(在AArch64模式下)UMULH,否则UMULL。)这是我想使用fast64x64=128
还是我想知道/学习/练习如何实现fast64x64=128
?对于前者,一个有自尊心的编译器应该能够指导您。(carry handling本身会扼杀任何优势。
或者?)我“不”知道所展示的代码正在尝试做什么(可能成功)。它看起来当然不是64x64=128。从VMULL.U32
开始,只需执行“长乘法”:在操作数如此小(支持的因子长度的两倍)的情况下,单靠进位处理将消除需要较少乘法的任何优势。(甚至(在AArch64模式下)UMULH,否则UMULL。)这是我想使用fast64x64=128
还是我想知道/学习/练习如何实现fast64x64=128
?对于前者,一个有自尊心的编译器应该能够指导您。(carry-handling单独使用将扼杀任何优势
or?)