无心人 发表于 2008-3-18 21:23:55

上面代码可修改所有的数据重排指令的源到寄存器
可能能节约时间
不过要占两个XMM
刚粗略看了,似乎可抽出XMM5, XMM6缓存left, right
==============
想到另外一种拆解方法
假设xmm0 = 1:0/0:1
movq xmm1, xmm0
pshufd xmm1, xmm1, 11011100b
psrldq mm0, 8
pshufd xmm0, xmm0, 11011100b
paddq xmm0, xmm1
明天测试, 感觉指令安排比原来的好, 运算冲突少, 还能节约个xmm7
另外
GxQ在CSDN上的96bit算法不知道怎么处理的进位?
通篇没有比较和置位处理
或者我没看懂?
恐怕128bit再加就没这么容易了

gxqcn 发表于 2008-3-19 08:44:18

我将续写“诡异”算法的传奇,请稍候。。。:)

无心人 发表于 2008-3-19 08:59:51

64位长加?
我考虑下
不过感觉应该不能达到最优化效果
即比我上面写的SSE2 107条代码做多节约30%时间
你先别发, 等我代码调试好了发上去
你再发,好对比

无心人 发表于 2008-3-19 11:46:30

void UInt128x128To256_SSE2_54F( UINT32 * const result,
                                                           const UINT32 * const left,
                                                           const UINT32 * const right )
{
        //全SSE2版本
        __asm
        {
                /* 具体代码在下一个代码区,需登陆才可见 */
                mov esi, dword ptr
                mov edi, dword ptr
                mov ebx, dword ptr
                movdqu xmm5,
                movdqu xmm6,
                pshufd xmm0, xmm5, 11011100b//2008-03-21 有修改
                pshufd xmm1, xmm6, 11011100b//2008-03-21 有修改
      pmuludq xmm0, xmm1
                pcmpeqd xmm7, xmm7
      psrlq xmm7, 32 //00000000FFFFFFFF00000000FFFFFFFF
                movd , xmm0 //0:0结果低位保存
                pshufd xmm1, xmm5, 00010000b
                pshufd xmm2, xmm6, 00000001b
                pmuludq xmm1, xmm2 //xmm1= 1:0/0:1
                movq xmm4, xmm0
      pshufd xmm4, xmm4, 11111101b
                pshufd xmm3, xmm1, 00010000b
                pand xmm3, xmm7
                pshufd xmm2, xmm1, 00110010b
                pand xmm2, xmm7
                paddq xmm2, xmm3 //0:1+1:0=xmm2
                paddq xmm2, xmm4
                psrldq xmm0, 8
//xmm0=1:1
                movd , xmm2
                psrldq xmm2, 4
                pshufd xmm3, xmm2, 11111001b
                pshufd xmm2, xmm2, 11111100b
                paddq xmm2, xmm3
//2:0 0:2
                pshufd xmm4, xmm5, 00100000b
                pshufd xmm3, xmm6, 00000010b
                pmuludq xmm4, xmm3 //xmm4=2:0/0:2
                pshufd xmm3, xmm4, 00010000b
                pand xmm3, xmm7
                pshufd xmm4, xmm4, 00110010b
                pand xmm4, xmm7
                paddq xmm3, xmm4 //xmm3=2:0 + 0:2 xmm0=1:1 xmm2=进位
                pshufd xmm0, xmm0, 11011100b
                paddq xmm3, xmm2
                paddq xmm3, xmm0
                movd , xmm3
                psrldq xmm3, 4
                pshufd xmm0, xmm3, 11111001b
                pshufd xmm3, xmm3, 11111100b
                paddq xmm0, xmm3 //xmm0=进位
//1:2 2:1 3:0 0:3
      pshufd xmm1, xmm5, 00010010b
                pshufd xmm4, xmm6, 00100001b
                pmuludq xmm1, xmm4
                pshufd xmm2, xmm5, 00110000b
                pshufd xmm3, xmm6, 00000011b
                pmuludq xmm2, xmm3 //xmm0进位 xmm1=1:2/2:1 xmm2=3:0/0:3
      pshufd xmm4, xmm1, 00010000b
                pand xmm4, xmm7
                pshufd xmm1, xmm1, 00110010b
                pand xmm1, xmm7
                paddq xmm1, xmm4
                paddq xmm0, xmm1
                pshufd xmm3, xmm2, 00010000b
                pand xmm3, xmm7
                pshufd xmm2, xmm2, 00110010b
                pand xmm2, xmm7
                paddq xmm2, xmm3
                paddq xmm0, xmm2
                movd , xmm0
                psrldq xmm0, 4
                pshufd xmm3, xmm0, 11111001b
                pshufd xmm0, xmm0, 11111100b
                paddq xmm0, xmm3 //xmm0进位
//1:3 2:2 3:1
      pshufd xmm1, xmm5, 00110010b
                pshufd xmm3, xmm6, 00110010b
                pmuludq xmm1, xmm3 //xmm1=3:3/2:2
                pshufd xmm2, xmm5, 00110001b
                pshufd xmm4, xmm6, 00010011b
      pmuludq xmm2, xmm4 //xmm2=3:1/1:3
      movdqa xmm4, xmm1
                psrldq xmm4, 8 //xmm4=3:3
                movq xmm1, xmm1 //xmm1=2:2
                pshufd xmm3, xmm2, 00110010b
                pand xmm3, xmm7
                pshufd xmm2, xmm2, 00010000b
                pand xmm2, xmm7
                paddq xmm2, xmm3
                pshufd xmm1, xmm1, 11011100b
                paddq xmm1, xmm2
                paddq xmm0, xmm1
                movd , xmm0
                psrldq xmm0, 4
                pshufd xmm3, xmm0, 11111001b
                pshufd xmm0, xmm0, 11111100b
                paddq xmm0, xmm3 //xmm0=进位
//2:3 3:2
      pshufd xmm1, xmm5, 00100011b
                pshufd xmm2, xmm6, 00110010b
                pmuludq xmm1, xmm2
                pshufd xmm3, xmm1, 00010000b
      pand xmm3, xmm7
                pshufd xmm1, xmm1, 00110010b
                pand xmm1, xmm7
                paddq xmm1, xmm3
                paddq xmm0, xmm1
                movd , xmm0
                psrldq xmm0, 4
                pshufd xmm2, xmm0, 11111001b
                pshufd xmm0, xmm0, 11111100b
                paddq xmm0, xmm2 //进位
      pshufd xmm4, xmm4, 11011100b
                paddq xmm0, xmm4
                movd , xmm0
                psrldq xmm0, 4
                pshufd xmm1, xmm0, 11111001b
                pshufd xmm0, xmm0, 11111100b
                paddq xmm0, xmm1
                movd , xmm0
      //                ret;
        }
}

//MMX    1 681 885us
//SSE2s  1 841 345us
//SSE2   1 841 528us 

无心人 发表于 2008-3-19 11:48:01

111行

gxqcn 发表于 2008-3-23 21:15:41

我的“诡异”算法

_declspec(naked)
void UInt128x128To256_SSE2_56F( UINT32 * const result,
                              const UINT32 * const left,
                              const UINT32 * const right )
{
    __asm
    {
      mov         ecx, dword ptr   ; result
      mov         eax, dword ptr   ; left
      mov         edx, dword ptr   ; right

      movdqa      xmm2, xmmword ptr      ; load left
      movdqa      xmm0, xmmword ptr      ; load right

      pshufd      xmm7, xmm2, 11111111b       ; xmm7 = L3:L3:L3:L3
      pshufd      xmm1, xmm0, 11110101b       ; xmm1 = R3:R3:R1:R1
      movdqa      xmm6, xmm7                  ; xmm6 = L3:L3:L3:L3

      pmuludq   xmm7, xmm1                  ; xmm7 = L3*R3:L3*R1 ->V7-4
      pmuludq   xmm6, xmm0                  ; xmm6 = L3*R2:L3*R0 ->V6-3

      movdqa      xmm5, xmm7                  ;
      movdqa      xmm4, xmm6                  ;
      movdqa      xmm3, xmm6                  ;

      pslldq      xmm5, 4                     ; xmm5 <<= 32
      psrldq      xmm4, 4                     ; xmm4 >>= 32
      pslldq      xmm3, 12                  ; L3*R2:L3*R0 ->V3-0

      paddq       xmm6, xmm5                  ; L3*R3:L3*R1 ->V6-3
      paddq       xmm7, xmm4                  ; L3*R2:L3*R0 ->V7-4


      pshufd      xmm5, xmm2, 10101010b       ; xmm5 = L2:L2:L2:L2
      pmuludq   xmm5, xmm1                  ; xmm5 = L2*R3:L2*R1

      paddq       xmm6, xmm5                  ; L2*R3:L2*R1 ->V6-3
      movdqa      xmm4, xmm5                  ;

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm4, 12                  ; xmm4 <<= 96

      paddq       xmm7, xmm5                  ; L2*R3:L2*R1 ->V7-4
      paddq       xmm3, xmm4                  ; L2*R3:L2*R1 ->V3-0


      pshufd      xmm5, xmm2, 10101010b       ; xmm5 = L2:L2:L2:L2
      pshufd      xmm4, xmm2, 01010101b       ; xmm4 = L1:L1:L1:L1
      pshufd      xmm2, xmm2, 00000000b       ; xmm2 = L0:L0:L0:L0

      pmuludq   xmm5, xmm0                  ; xmm5 = L2*R2:L2*R0

      movdqa      xmmword ptr, xmm4 ; xmm4 = L1:L1:L1:L1
      movdqa      xmmword ptr, xmm2 ; xmm2 = L0:L0:L0:L0
      movdqa      xmm2, xmm5                  ; xmm2 = L2*R2:L2*R0

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm2, 8                     ; xmm4 <<= 64

      paddq       xmm6, xmm5                  ; L2*R2:L2*R0 ->V6-3
      paddq       xmm3, xmm2                  ; L2*R2:L2*R0 ->V3-0

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm2, 4                     ; L2*R2:L2*R0 ->V2-1H

      paddq       xmm7, xmm5                  ; L2*R2:L2*R0 ->V7-4


      movdqa      xmm5, xmmword ptr ; xmm5 = L1:L1:L1:L1
      pmuludq   xmm5, xmm1                  ; xmm5 = L1*R3:L1*R1
      movdqa      xmm4, xmm5                  ;

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm4, 8                     ; xmm4 >>= 64

      paddq       xmm6, xmm5                  ; L1*R3:L1*R1 ->V6-3
      paddq       xmm3, xmm4                  ; L1*R3:L1*R1 ->V3-0

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm7, xmm5                  ; L1*R3:L1*R1 ->V7-4
      paddq       xmm2, xmm4                  ; L1*R3:L1*R1 ->V2-1H

      movdqa      xmm5, xmmword ptr ; xmm5 = L1:L1:L1:L1
      pmuludq   xmm5, xmm0                  ; xmm5 = L1*R2:L1*R0

      movdqa      xmm4, xmm5                  ;

      psrldq      xmm5, 8                     ; xmm5 >>= 64
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm6, xmm5                  ; L1*R2:L1*R0 ->V6-3
      paddq       xmm3, xmm4                  ; L1*R2:L1*R0 ->V3-0

      psrldq      xmm5, 4                     ; xmm5 >>= 32
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm7, xmm5                  ; L1*R2:L1*R0 ->V7-4
      paddq       xmm2, xmm4                  ; L1*R2:L1*R0 ->V2-1H


      movdqa      xmm5, xmmword ptr ; xmm5 = L0:L0:L0:L0
      pmuludq   xmm5, xmm1                  ; xmm5 = L0*R3:L0*R1

      movdqa      xmm4, xmm5                  ;

      psrldq      xmm5, 8                     ; xmm5 >>= 64
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm6, xmm5                  ; L0*R3:L0*R1 ->V6-3
      paddq       xmm3, xmm4                  ; L0*R3:L0*R1 ->V3-0

      psrldq      xmm5, 4                     ; xmm5 >>= 64
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm7, xmm5                  ; L0*R3:L0*R1 ->V7-4
      paddq       xmm2, xmm4                  ; L0*R3:L0*R1 ->V2-1H

      movdqa      xmm5, xmmword ptr ; xmm5 = L0:L0:L0:L0
      pmuludq   xmm5, xmm0                  ; xmm5 = L0*R2:L0*R0

      paddq       xmm3, xmm5                  ; L0*R2:L0*R0 ->V3-0
      movdqa      xmm4, xmm5                  ;

      psrldq      xmm5, 12                  ; xmm5 >>= 96
      pslldq      xmm4, 4                     ; xmm4 >>= 32

      paddq       xmm6, xmm5                  ; L0*R2:L0*R0 ->V6-3
      paddq       xmm2, xmm4                  ; L0*R2:L0*R0 ->V2-1H


      ; now, V=xmm3 ->OK
      psrldq      xmm2, 4                     ; xmm2 >>= 32
      movdqa      xmm4, xmm3                  ;
      pcmpeqd   xmm0, xmm0                  ; xmm0 = FF:FF:FF:FF
      pandn       xmm4, xmm2                  ;
      psubd       xmm2, xmm3                  ; xmm2 -= xmm3
      psrldq      xmm0, 12                  ; xmm0 = 00:00:00:FF

      pslldq      xmm4, 4                     ; xmm4 <<= 32
      psrld       xmm4, 31                  ; CF
      pshufd      xmm1, xmm0, 01001110b       ; xmm1 = 00:FF:00:00
      paddd       xmm2, xmm4                  ;
      pand      xmm2, xmm1                  ;
      paddq       xmm3, xmm2                  ; V=xmm3 ->OK
      movdqa      xmmword ptr, xmm3 ; store V


      psrldq      xmm3, 12                  ; xmm3 >>= 96
      psubd       xmm3, xmm6                  ; xmm3 -= xmm6
      pand      xmm3, xmm0                  ;
      paddq       xmm6, xmm3                  ; V=xmm6 ->OK
      pxor      xmm1, xmm0                  ; xmm1 = 00:FF:00:FF
      psrldq      xmm6, 4                     ; V=xmm6 ->OK


      movdqa      xmm2, xmm6                  ; xmm2 = xmm6
      psubd       xmm6, xmm7                  ; xmm6 -= xmm0
      pand      xmm6, xmm1                  ;
      paddq       xmm7, xmm6                  ; now, xmm7 bits OK!

      psubusb   xmm2, xmm7                  ;
      psrlq       xmm2, 63                  ; CF
      pslldq      xmm2, 8                     ;
      paddq       xmm7, xmm2                  ; xmm7 += CF
      movdqa      xmmword ptr, xmm7 ; store V

      ret;
    }
}SSE2 指令,XMM 寄存器,110行(包含最后那个 ret 指令)。
(费了不少功夫,但效果没有预期的好)

无心人 发表于 2008-3-23 21:22:05

你算法优势不大了

movdqa                xmm2, xmmword ptr                ; load      left
movdqa                xmm0, xmmword ptr                ; load      right
最好用pshufd代替, 有性能改进的
==============================================================================
就不另外开新回复了
我想在我代码测试里你也看到了
明明SSE2一次乘两个,却和一个乘一个的差不多,更离谱的是和用MMX寄存器的时间差了好多
关键是
1、目前的乘法,SSE2乘一次延迟是5,用MMX一次是3,这个影响不大
2、简单乘一个导致后期处理简单
3、似乎某些设计导致MMX寄存器快
如果有Core 2的结果最好了,Core 2应该能改进甚至导致SSE2的双乘算法超过MMX寄存器

gxqcn 发表于 2008-3-24 10:49:01

改进版

在 56# 基础上改进,主要目的是让 pmuludq 指令集中执行,消除其延时,代码如下:_declspec(naked)
void UInt128x128To256_SSE2_58F( UINT32 * const result,
                              const UINT32 * const left,
                              const UINT32 * const right )
{
    __asm
    {
      mov         ecx, dword ptr   ; result
      mov         eax, dword ptr   ; left
      mov         edx, dword ptr   ; right

      movdqa      xmm5, xmmword ptr      ; load left
      movdqa      xmm4, xmmword ptr      ; load right

      mov         eax, esp                  ;
      sub         esp, 0x4F                   ;
      and         esp, -16                  ;

      pshufd      xmm0, xmm5, 00000000b       ; xmm0 = L0:L0:L0:L0
      pshufd      xmm1, xmm5, 01010101b       ; xmm1 = L1:L1:L1:L1
      pshufd      xmm2, xmm5, 10101010b       ; xmm2 = L2:L2:L2:L2
      pshufd      xmm3, xmm5, 11111111b       ; xmm3 = L3:L3:L3:L3

      movdqa      xmmword ptr, xmm0 ; xmm0 = L0:L0:L0:L0
      movdqa      xmmword ptr, xmm1 ; xmm1 = L1:L1:L1:L1
      movdqa      xmm6, xmm2                  ; xmm6 = L2:L2:L2:L2
      movdqa      xmm7, xmm3                  ; xmm7 = L3:L3:L3:L3

      pmuludq   xmm0, xmm4                  ; xmm0 = L0*R2:L0*R0
      pmuludq   xmm1, xmm4                  ; xmm1 = L1*R2:L1*R0
      pmuludq   xmm2, xmm4                  ; xmm2 = L2*R2:L2*R0
      pmuludq   xmm3, xmm4                  ; xmm3 = L3*R2:L3*R0

      movdqa      xmmword ptr, xmm0 ;
      movdqa      xmmword ptr, xmm1 ;
      movdqa      xmmword ptr, xmm2 ;
      movdqa      xmmword ptr, xmm3 ;

      psrldq      xmm4, 4                     ; xmm4 = 00:R3:R2:R1
      movdqa      xmm1, xmmword ptr ; xmm1 = L1:L1:L1:L1
      movdqa      xmm0, xmmword ptr ; xmm0 = L0:L0:L0:L0

      pmuludq   xmm7, xmm4                  ; xmm3 = L3*R3:L3*R1 ->V7-4
      pmuludq   xmm6, xmm4                  ; xmm2 = L2*R3:L2*R1 ->V6-3
      pmuludq   xmm1, xmm4                  ; xmm1 = L1*R3:L1*R1
      pmuludq   xmm0, xmm4                  ; xmm0 = L0*R3:L0*R1


      movdqa      xmm5, xmm7                  ;
      movdqa      xmm4, xmm6                  ;
      movdqa      xmm3, xmm6                  ;

      pslldq      xmm5, 4                     ; xmm5 <<= 32
      psrldq      xmm4, 4                     ; xmm4 >>= 32
      pslldq      xmm3, 12                  ; L3*R3:L3*R1 ->V3-0

      paddq       xmm7, xmm4                  ; L2*R3:L2*R1 ->V7-4
      paddq       xmm6, xmm5                  ; L3*R3:L3*R1 ->V6-3


      movdqa      xmm2, xmm0                  ;
      movdqa      xmm4, xmm0                  ;
      movdqa      xmm5, xmm1                  ;

      psrldq      xmm0, 8                     ; xmm0 >>= 64
      psrldq      xmm1, 4                     ; xmm1 >>= 32
      pslldq      xmm2, 8                     ; L0*R3:L0*R1 ->V2-1H
      pslldq      xmm4, 4                     ; xmm4 <<= 32
      pslldq      xmm5, 8                     ; xmm5 <<= 64

      paddq       xmm6, xmm0                  ; L0*R3:L0*R1 ->V6-3
      paddq       xmm3, xmm4                  ; L0*R3:L0*R1 ->V3-0
      paddq       xmm6, xmm1                  ; L1*R3:L1*R1 ->V6-3
      paddq       xmm3, xmm5                  ; L1*R3:L1*R1 ->V3-0

      psrldq      xmm0, 4                     ; xmm0 >>= 32
      psrldq      xmm1, 4                     ; xmm1 >>= 32
      pslldq      xmm5, 4                     ; xmm5 <<= 32

      paddq       xmm7, xmm0                  ; L0*R3:L0*R1 ->V7-4
      paddq       xmm2, xmm5                  ; L1*R3:L1*R1 ->V2-1H
      paddq       xmm7, xmm1                  ; L1*R3:L1*R1 ->V7-4


      movdqa      xmm5, xmmword ptr ; xmm5 = L3*R2:L3*R0
      movdqa      xmm4, xmmword ptr ; xmm4 = L2*R2:L2*R0

      movdqa      xmm1, xmm5                  ;
      movdqa      xmm0, xmm4                  ;
      paddq       xmm6, xmm5                  ; L3*R2:L3*R0 ->V6-3

      psrldq      xmm0, 4                     ; xmm0 >>= 32
      psrldq      xmm1, 4                     ; xmm1 >>= 32
      pslldq      xmm4, 8                     ; xmm4 <<= 64
      pslldq      xmm5, 12                  ; xmm5 <<= 96

      paddq       xmm6, xmm0                  ; L2*R2:L2*R0 ->V6-3
      paddq       xmm3, xmm4                  ; L2*R2:L2*R0 ->V3-0
      paddq       xmm7, xmm1                  ; L3*R2:L3*R0 ->V7-4
      paddq       xmm3, xmm5                  ; L3*R2:L3*R0 ->V3-0

      psrldq      xmm0, 4                     ; xmm0 >>= 32
      pslldq      xmm4, 4                     ; xmm4 <<= 32

      paddq       xmm7, xmm0                  ; L2*R2:L2*R0 ->V7-4
      paddq       xmm2, xmm4                  ; L2*R2:L2*R0 ->V2-1H


      movdqa      xmm0, xmmword ptr ; xmm0 = L0*R2:L0*R0
      movdqa      xmm1, xmmword ptr ; xmm1 = L1*R2:L1*R0

      mov         esp, eax                  ;

      paddq       xmm3, xmm0                  ; L0*R2:L0*R0 ->V3-0

      movdqa      xmm4, xmm0                  ;
      movdqa      xmm5, xmm1                  ;

      pslldq      xmm0, 4                     ; xmm0 <<= 32
      pslldq      xmm1, 4                     ; xmm1 <<= 32
      psrldq      xmm4, 12                  ; xmm4 >>= 96
      psrldq      xmm5, 8                     ; xmm5 >>= 64

      paddq       xmm2, xmm0                  ; L0*R2:L0*R0 ->V2-1H
      paddq       xmm6, xmm4                  ; L0*R2:L0*R0 ->V6-3
      paddq       xmm3, xmm1                  ; L1*R2:L1*R0 ->V3-0
      paddq       xmm6, xmm5                  ; L1*R2:L1*R0 ->V6-3

      pslldq      xmm1, 4                     ; xmm1 <<= 32
      psrldq      xmm5, 4                     ; xmm5 >>= 32

      paddq       xmm2, xmm1                  ; L1*R2:L1*R0 ->V2-1H
      paddq       xmm7, xmm5                  ; L1*R2:L1*R0 ->V7-4


      ; now, V=xmm3 ->OK
      psrldq      xmm2, 4                     ; xmm2 >>= 32
      movdqa      xmm4, xmm3                  ;
      pcmpeqd   xmm0, xmm0                  ; xmm0 = FF:FF:FF:FF
      pandn       xmm4, xmm2                  ;
      psubd       xmm2, xmm3                  ; xmm2 -= xmm3
      psrldq      xmm0, 12                  ; xmm0 = 00:00:00:FF

      pslldq      xmm4, 4                     ; xmm4 <<= 32
      psrld       xmm4, 31                  ; CF
      pshufd      xmm1, xmm0, 01001110b       ; xmm1 = 00:FF:00:00
      paddd       xmm2, xmm4                  ;
      pand      xmm2, xmm1                  ;
      paddq       xmm3, xmm2                  ; V=xmm3 ->OK
      movdqa      xmmword ptr, xmm3 ; store V


      psrldq      xmm3, 12                  ; xmm3 >>= 96
      psubd       xmm3, xmm6                  ; xmm3 -= xmm6
      pand      xmm3, xmm0                  ;
      paddq       xmm6, xmm3                  ; V=xmm6 ->OK
      pxor      xmm1, xmm0                  ; xmm1 = 00:FF:00:FF
      psrldq      xmm6, 4                     ; V=xmm6 ->OK


      movdqa      xmm2, xmm6                  ; xmm2 = xmm6
      psubd       xmm6, xmm7                  ; xmm6 -= xmm0
      pand      xmm6, xmm1                  ;
      paddq       xmm7, xmm6                  ; now, xmm7 bits OK!

      psubusb   xmm2, xmm7                  ;
      psrlq       xmm2, 63                  ; CF
      pslldq      xmm2, 8                     ;
      paddq       xmm7, xmm2                  ; xmm7 += CF
      movdqa      xmmword ptr, xmm7 ; store V

      ret;
    }
}全函数 121 条汇编指令(含 ret 指令),无跳转,无 adc 指令。

测试结果如下:UInt128x128To256_ANSI_C32(..): 679.753ms
UInt128x128To256_SSE2_40F(..): 479.048ms
UInt128x128To256_SSE2_42F(..): 809.487ms
UInt128x128To256_SSE2_54F(..): 754.158ms
UInt128x128To256_SSE2_56F(..): 640.666ms
UInt128x128To256_SSE2_58F(..): 625.339ms
测试环境:Windows XP SP2,AMD Athlon 64 Processor 3200+,1GB DDR - 200MHz
(欢迎大家在本地机上测试)

当前所有版本测试源代码及编译好的程序压缩包:
(注意:在 69# 有更新更全的压缩包)

liangbch 发表于 2008-3-24 11:27:32

报个到先. 本来说不打算参与了,看你们写了这么多版本,我也试一试写SSE2版的。
主要采用SSE2指令乘,一次只做一个32bit*32bit,进位部分采用利用 SSE2指令做 64bit + 32bit的运算,中间结果使用 MMX存储。
预期的速度应该难以超越gxq,但应该不会太慢。

gxqcn 发表于 2008-3-24 11:43:28

我写的仍无法超越楼主在 40# 里的“SSE2指令/MMX寄存器”版本。:)
不知在 Core 2 上的结果会如何?:o

这次与先前的 UInt96x96To192 不一样,对进位处理更麻烦,
而我的所谓“诡异算法”似乎并不凑效,所以比我快的可能性仍很高。:)
页: 1 2 3 4 5 [6] 7 8 9 10 11 12 13 14 15
查看完整版本: x86上128位二进制乘法最快速算法征解