1

我在互联网上找到了许多用于 ARM NEON 的 Karatsuba 算法的相同实现的副本,包括一些科学论文,例如 http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf

看起来所有这些副本都有相同的故障。虽然说它进行算术乘法,但结果仍然是多项式。如果将 更改为vmull.p8vmull.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

但为什么它不像所说的那样正确?基本上我需要一个高效的 64x64=128 arm-v7a 算术运算,看起来 NEON 是这里唯一的选择。

感觉就像在这些操作中的某个地方丢失了一个进位标志,因为我观察到的结果非常接近正确的结果。

4

0 回答 0