- 注册时间
- 2007-12-28
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 12785
- 在线时间
- 小时
|
发表于 2008-3-26 21:58:52
|
显示全部楼层
写了一个 使用 MMX 寄存器,SSE2 乘 和 加 指令的版本,速度大幅领先于 现有的所有版本。
先贴上测试结果(PIV 2.6G 768M RAM),为了避免将函数调用放在后面容易占优势的嫌疑,将对该函数的调用放在前面。
Test function: UInt128x128To256_ANSI_C32(..) 10000000 times...
Elapsed time: 2035.286 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_76F(..) 10000000 times...
Elapsed time: 395.657 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_40F(..) 10000000 times...
Elapsed time: 1027.907 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_42F(..) 10000000 times...
Elapsed time: 762.286 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_54F(..) 10000000 times...
Elapsed time: 734.089 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_56F(..) 10000000 times...
Elapsed time: 607.176 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_58F(..) 10000000 times...
Elapsed time: 923.039 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
Test function: UInt128x128To256_SSE2_69F(..) 10000000 times...
Elapsed time: 529.028 ms
92F84935 2DD0353C A7166445 8B52280D * ADBE65FA 33EC4DD6 F39E291C 6C1A072B
= 63BF184A DE964DAC 8CD871A5 3FB4A4E7 D031F0A2 D4767BD7 A7C40427 3337152F
再贴上所有源代码(注意:该版有bug,作者已在 96# 修正!--gxqcn)- _declspec(naked) /* 注意:该版有bug,作者已在 96# 修正!*/
- void UInt128x128To256_SSE2_76F( UINT32 * const result,
- const UINT32 * const left,
- const UINT32 * const right )
- // 使用MMX寄存器, 但用SSE2指令
- // 指令的使用,乘法 使用 32bit * 32bit 的MMX指令,加法使用 64 bit + 64 bit 的SSE2指令
-
- // 16次乘法,分4趟, 操作数一律在mmx 寄存器中进行
- // 第1趟计算 left[] * right[0]
- // 第2趟计算 left[] * right[1]
- // 第3趟计算 left[] * right[2]
- // 第4趟计算 left[] * right[3]
-
- // 每趟的计算结果为 5 DWORD,最低位DWORD 直接存储到result, 前3趟的计算结果的高4个DWORD(中间结果)存储到一组寄存器
-
- // 寄存器的使用
-
- // 中间结果 放入 mm0,mm1,mm2,mm3
-
- // 掩码寄存器 mm7, 用来请64位寄存器的高32bit
- // 进位 寄存器 和 当前乘积寄存器 为 mm4 和 mm5,轮换使用
- // 乘数 寄存器 mm6
- // 可以看到8个mmx寄存器全部派上用场
-
- {
- #define LEFT_REG eax
- #define RIGHT_REG edx
- #define RESULT_REG ecx
- #define MASK_REG mm7
- #define MUL_REG mm6
-
- __asm
- {
- mov eax, 0xffffffff
- mov RESULT_REG, dword ptr[esp + 04h] ; result
- movd MASK_REG, eax
-
- mov RIGHT_REG, dword ptr[esp + 0Ch] ; right
- movq MUL_REG, [RIGHT_REG]
- mov LEFT_REG, dword ptr [esp + 08h] ; left
-
-
- //--------第1次乘
- movd mm4, [LEFT_REG+0]
- pmuludq mm4, MUL_REG
- movd [RESULT_REG], mm4
- psrlq mm4, 32 //carry
-
- //------第2次乘
- movd mm5, [LEFT_REG+4]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- movq mm0, mm5
- psrlq mm5, 32 //carry
- pand mm0, MASK_REG //mm0,中间结果
-
- //------第3次乘
- movd mm4, [LEFT_REG+8]
- pmuludq mm4, MUL_REG
- paddq mm4, mm5 //64bit + 32 bit carry
- movq mm1, mm4
- psrlq mm4, 32 //carry
- pand mm1, MASK_REG //mm1,中间结果
-
- //------第4次乘
- movd mm5, [LEFT_REG+12]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- movq mm2, mm5
- psrlq mm5, 32 //carry
- pand mm2, MASK_REG //mm2,中间结果
- movq mm3, mm5 //mm3,中间结果
-
- //----得到乘数
- psrlq MUL_REG, 32 //得到right[1]
-
-
- //---第二趟乘---------
-
- //--------第5次乘
- movd mm4, [LEFT_REG+0]
- pmuludq mm4, MUL_REG
- paddq mm4, mm0 // 64bit + 32 bit 中间结果
- movd [RESULT_REG+4], mm4
- psrlq mm4, 32 //carry
-
- //------第6次乘
- movd mm5, [LEFT_REG+4]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm1 //64bit + 32 bit 中间结果
- movq mm0, mm5
- psrlq mm5, 32 //carry
- pand mm0, MASK_REG //mm0,中间结果
-
- //------第7次乘
- movd mm4, [LEFT_REG+8]
- pmuludq mm4, MUL_REG
- paddq mm4, mm5 //64bit + 32 bit carry
- paddq mm4, mm2 //64bit + 32 bit 中间结果
- movq mm1, mm4
- psrlq mm4, 32 //carry
- pand mm1, MASK_REG //mm1,中间结果
-
- //------第8次乘
- movd mm5, [LEFT_REG+12]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm3 //64bit + 32 bit 中间结果
- movq mm2, mm5
- psrlq mm5, 32 //carry
- pand mm2, MASK_REG //mm2,中间结果
- movq mm3, mm5 //mm3,中间结果
-
- //----得到乘数
- movq MUL_REG, [RIGHT_REG+8]
-
- //--------第9次乘
- movd mm4, [LEFT_REG+0]
- pmuludq mm4, MUL_REG
- paddq mm4, mm0 // 64bit + 32 bit 中间结果
- movd [RESULT_REG+8], mm4
- psrlq mm4, 32 //carry
-
- //------第10次乘
- movd mm5, [LEFT_REG+4]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm1 //64bit + 32 bit 中间结果
- movq mm0, mm5
- psrlq mm5, 32 //carry
- pand mm0, MASK_REG //mm0,中间结果
-
- //------第11次乘
- movd mm4, [LEFT_REG+8]
- pmuludq mm4, MUL_REG
- paddq mm4, mm5 //64bit + 32 bit carry
- paddq mm4, mm2 //64bit + 32 bit 中间结果
- movq mm1, mm4
- psrlq mm4, 32 //carry
- pand mm1, MASK_REG //mm1,中间结果
-
- //------第12次乘
- movd mm5, [LEFT_REG+12]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm3 //64bit + 32 bit 中间结果
- movq mm2, mm5
- psrlq mm5, 32 //carry
- pand mm2, MASK_REG //mm2,中间结果
- movq mm3, mm5 //mm3,中间结果
-
-
- //----得到乘数
- psrlq MUL_REG, 32 //得到right[1]
-
- //--------第13次乘
- movd mm4, [LEFT_REG+0]
- pmuludq mm4, MUL_REG
- paddq mm4, mm0 // 64bit + 32 bit 中间结果
- movd [RESULT_REG+12], mm4
- psrlq mm4, 32 //carry
-
- //------第14次乘
- movd mm5, [LEFT_REG+4]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm1 //64bit + 32 bit 中间结果
- movd [RESULT_REG+16], mm5
- psrlq mm5, 32 //carry
-
-
- //------第15次乘
- movd mm4, [LEFT_REG+8]
- pmuludq mm4, MUL_REG
- paddq mm4, mm5 //64bit + 32 bit carry
- paddq mm4, mm2 //64bit + 32 bit 中间结果
- movd [RESULT_REG+20], mm4
- psrlq mm4, 32 //carry
-
-
- //------第16次乘
- movd mm5, [LEFT_REG+12]
- pmuludq mm5, MUL_REG
- paddq mm5, mm4 //64bit + 32 bit carry
- paddq mm5, mm3 //64bit + 32 bit 中间结果
- movq [RESULT_REG+24], mm5
- psrlq mm5, 32 //carry
-
- //------保存最高DWORD
- movq [RESULT_REG+28], mm5 //mm3,中间结果
-
- //emms
- ret
- }
- }
复制代码 我的指令数为111条,指令数可能是所有版本中最小的。 |
|