找回密码
 欢迎注册
楼主: mathe

[擂台] 平方数数字和

[复制链接]
发表于 2008-7-30 07:47:31 | 显示全部楼层
找到不进行分支而进位的SIMD写法
假设
XMM0保存平方
XMM7保存Delta
XMM6保存四个10000
XMM5保存四个1

pmovdqa xmm3, xmm0
pcmpged xmm3, xmm6
pmovdqa xmm4, xmm3
pand xmm3, xmm6
paddd xmm0, xmm3
psldq  xmm4,  4
pand  xmm4, xmm5
psubd xmm0, xmm4
则顺序执行三次就可调整三个进位
现在问题是
如果一次装8个word,执行7次,则可完全调整
如果像上面一次4个dword,还需要中间把最高位双字单独处理次
还有就是不知道这么多条指令并行度如何?粗略略计算是6个时钟
感觉是用dword做好些,重复7次完成调整
同样道理delta的加2也可重复三次完成
至于溢出,我想暂时遇不到,呵呵
毕竟好几年才能溢出的
谁测试下啊?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-30 09:12:12 | 显示全部楼层
其实,本算法主要是加减、进位等算术指令,
用 ALU 算术单元足矣,比 SIMD 更划算,尤其是涉及到有进位处理的过程。

ALU 指令可以 U、V 双通道并行,
且进位处理过程中的跳转指令完全可由非跳转指令替代
(需手工编写汇编代码,我不相信编译有如此智能),
即可完全消除因跳转预测失败带来的惩罚,
由此速度将可大幅提高,甚至提速1倍以上!

但我不想在此花这个功夫去优化了,
因为需要手工编写大量的汇编代码。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-30 09:51:18 | 显示全部楼层


老大啊
你还说U, V通道么?
你应该知道U, V是PIII之前的东西了
P4是5个执行单元哦

另外,写汇编不比C代码复杂多少
呵呵,就是打字多点,调试麻烦些吧

你说的非跳转调整方式是什么意思?
ALU方式和SSE2 ALU方式延迟时间比是1:4,吞吐量比是1:2
但SSE2能一次处理8个word,正好是我们所用的范围
另外,我考虑用BTS指令处理位组合,似乎比数组写标志
要好些?

还有,似乎压缩数据大小到L1 Data是有可能实现的?
P4以上的CPU L1 Data Cache到底多大? 8k还是16k
==========================
刚知道了Free Pascal如何嵌入汇编了
考虑在学校的机器上也装个
呵呵
反正到汇编这个级别什么编译器都能写优化代码了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-30 12:51:42 | 显示全部楼层
GxQ是否打算使用CMOVcc指令?

  1. mov  eax, square
  2. add eax, delta
  3. mov ebx, square+4
  4. add ebx, delta+4
  5. mvo ecx, square+8
  6. add ecx, delta+8
  7. mov edx, square+12
  8. add edx, delta+12
  9. mov esi, eax
  10. sub esi, 10000
  11. cmovnc eax, esi
  12. cmc
  13. adc ebx, 0
  14. mov edi, ebx
  15. sub edi, 10000
  16. cmovnc ebx, edi
  17. cmc
  18. adc ecx, 0
  19. mov esi, ecx
  20. sub esi, 10000
  21. cmovnc ecx, esi
  22. cmc
  23. adc edx, 0
  24. mov edi, edx
  25. sub edi, 10000
  26. cmovnc edx, edi
  27. cmc
  28. adc  square+16, 0
  29. ....
  30. ....
复制代码
突然发现上面的代码很有意思
可能能大幅度减少代码使用条数
可以连数位和都一起算了
不过寄存器要节约点用了
呵呵
===========================
PS:
ADC, CMOVcc, CMC在P4上都是慢操作,Core2上好多了
可能这么写代码在Core2以上效果好很多吧
P4上不知道如何了,哎
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-30 20:07:11 | 显示全部楼层
下午测试了,似乎效果不很显著
因为一开始的计算不如原始的
多算了很多

在考虑是否先把目前的算法翻译成汇编

另外刚更新了137#的结果
和GxQ的结果持平了
再继续挂就会出新结果了
他计算了8小时,我想我这里要挂24小时出新结果吧
大概是明天这个时候看吧
如果还不出,恐怕以后出一个新结果就要等几天了
呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-30 22:04:33 | 显示全部楼层

回复 144# 无心人 的帖子

注意到我在 96# 中将几个数组合并为一个大数组,
这样在写汇编时可以更方便通过偏移进行定位。

另外,想请教一下:CMOVcc系列指令是否在后期的CPU都支持?包括64位系统下的?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-31 08:41:32 | 显示全部楼层
似乎是P5引入的吧
都支持的,包括64位
而且支持所有标志的
但似乎P4的延迟高些
Core2低的多了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-31 08:43:04 | 显示全部楼层
我把我新写的尽量少分支的Pasal贴上来GxQ看看吧
还有两个跳转无法消除,哎
另外程序得到和GxQ相同的结果后已运行了14小时了
还没出新结果,效率大约相当于GxQ程序的1/2
所以过4个小时将超越38小时的运行结果哦
  1. program square;

  2.   

  3. uses SysUtils;



  4. const

  5.         TenPower = 10000;

  6.         StatusFileName = 'Square.Status';

  7.         LogFileName = 'Square.Log';

  8.         BlockSize = 8;

  9.         BoolSize = 320;



  10. type

  11.         TStatus = record

  12.                 S:array[0..BoolSize - 1] of integer;

  13.                 SquareValue:array[0..BlockSize - 1]  of integer;       

  14.                 Delta:array[0..BlockSize - 1]  of integer;       

  15.         end;



  16. var

  17.   Status:TStatus;

  18.   StatusFile: File of TStatus;

  19.   LogFile:TextFile;

  20.   SumOfDigit4: array[0..TenPower - 1] of integer;

  21.   ExeFilePath: string;

  22.   Counter:Integer;

  23.   s: integer;



  24. procedure WriteLog (s:string);

  25. begin

  26.   Assign (LogFile, ExeFilePath + LogFileName);

  27.   if FileExists(ExeFilePath + LogFileName) then

  28.     Append (LogFile)

  29.   else

  30.     Rewrite (LogFile);

  31.   writeln (LogFile, s);

  32.   Close (LogFile);

  33. end;



  34. procedure InitStatus;

  35. var

  36.   i:integer;

  37. begin

  38.   for I := 0 to BoolSize - 1  do

  39.     Status.s[i]:= 0;

  40.   for i := 0 to BlockSize - 1 do

  41.   begin

  42.     status.SquareValue[i]:= 0;

  43.     status.delta[i]:= 0;

  44.   end;

  45.   Status.Delta[0]:= 1;

  46. end;



  47. procedure ReadStatus;

  48. begin

  49.   Assign (StatusFile, ExeFilePath + StatusFileName);

  50.   if FileExists(ExeFilePath + StatusFileName) then

  51.   begin

  52.     Reset (StatusFile);

  53.     Read (StatusFile, Status);

  54.     Close (StatusFile);

  55.   end

  56.   else

  57.     InitStatus;

  58.   end;



  59. procedure WriteStatus;

  60. begin

  61.   Assign (StatusFile, ExeFilePath + StatusFileName);

  62.   Rewrite (StatusFile);

  63.   Write (StatusFile, Status);

  64.   Close (StatusFile);

  65. end;



  66. procedure InitSumOfDigit4;

  67. var

  68.   i3, i2, i1, i0, k:integer;

  69. begin

  70.   k:= 0;

  71.   for I3 := 0 to 9  do

  72.           for I2 := 0 to 9  do

  73.             for I1 := 0 to 9   do

  74.                     for I0 := 0 to 9   do

  75.                     begin

  76.           SumOfDigit4[k]:= i3 + i2 + i1 +  i0;

  77.                       INC (k);

  78.                     end;

  79. end;



  80. procedure WriteResult;

  81. var

  82.   Str:String[128];

  83.   i:integer;

  84. begin

  85.   Str:= '';

  86.   for i  := BlockSize-1 downto 0  do

  87.     if Status.SquareValue[i] > 0 then

  88.       Str:= str + Format ('%4d', [Status.SquareValue[i]]);

  89.   writeln (DateTimeToStr (now) + ': ' + IntToStr (s) + ' ' +  str);

  90.   writelog (DateTimeToStr (now) + ': ' + IntToStr (s) +  ' ' + str);

  91. end;



  92. label label0, label1;



  93. begin

  94.   WriteLog ('程序启动: ' + DateTimeToStr (now));

  95.   WriteLn ('程序启动: ' + DateTimeToStr (now));

  96.   ExeFilePath:= ExtractFilePath (ParamStr(0));

  97.   Counter:= 0;

  98.   InitSumOfDigit4;

  99.   ReadStatus;

  100.   WriteLog ('初始化完成: ' + DateTimeToStr (now));

  101.   WriteLn ('初始化完成: ' + DateTimeToStr (now));



  102. //ADDDelta     

  103.   asm

  104. label0:

  105.     mov eax, dword ptr [Status.SquareValue]

  106.     add eax,dword ptr [Status.Delta]

  107.     mov ebx,dword ptr [Status.SquareValue + 4]

  108.     add ebx,dword ptr [Status.Delta + 4]

  109.     mov esi, eax

  110.     sub esi, TenPower

  111.     cmovnc eax, esi

  112.     cmc

  113.     adc ebx, 0

  114.     mov edx,dword ptr [SumOfDigit4 + 4 * eax]

  115.     mov dword ptr [Status.SquareValue], eax

  116.     mov eax,dword ptr [Status.SquareValue + 8]

  117.     add eax,dword ptr [Status.Delta + 8]

  118.     mov edi, ebx

  119.     sub edi, TenPower

  120.     cmovnc ebx, edi

  121.     cmc

  122.     adc eax, 0

  123.     mov dword ptr [Status.SquareValue + 4], ebx

  124.     add edx,dword ptr [SumOfDigit4 + 4 * ebx]

  125.     mov ebx,dword ptr [Status.SquareValue + 12]

  126.     add ebx,dword ptr [Status.Delta + 12]

  127.     mov esi, eax

  128.     sub esi, TenPower

  129.     cmovnc eax, esi

  130.     cmc

  131.     adc ebx, 0

  132.     mov dword ptr [Status.SquareValue + 8], eax

  133.     add edx,dword ptr [SumOfDigit4 + 4 * eax]

  134.     mov eax,dword ptr [Status.SquareValue + 16]

  135.     mov edi, ebx

  136.     sub edi, TenPower

  137.     cmovnc ebx, edi

  138.     cmc

  139.     adc eax, 0

  140.     mov dword ptr [Status.SquareValue + 12], ebx

  141.     add edx,dword ptr [SumOfDigit4 + 4 * ebx]

  142.     mov ebx,dword ptr [Status.SquareValue + 20]

  143.     mov esi, eax

  144.     sub esi, TenPower

  145.     cmovnc eax, esi

  146.     cmc

  147.     adc ebx, 0

  148.     mov dword ptr [Status.SquareValue + 16], eax

  149.     add edx,dword ptr [SumOfDigit4 + 4 * eax]

  150.     mov eax,dword ptr [Status.SquareValue + 24]

  151.     mov edi, ebx

  152.     sub edi, TenPower

  153.     cmovnc ebx, edi

  154.     cmc

  155.     adc eax, 0

  156.     mov dword ptr [Status.SquareValue + 20], ebx

  157.     add edx,dword ptr [SumOfDigit4 + 4 * ebx]

  158.     mov ebx,dword ptr [Status.SquareValue + 28]

  159.     mov esi, eax

  160.     sub esi, TenPower

  161.     cmovnc eax, esi

  162.     cmc

  163.     adc ebx, 0

  164.     mov dword ptr [Status.SquareValue + 24], eax

  165.     mov dword ptr [Status.SquareValue + 28], ebx

  166.     add edx,dword ptr [SumOfDigit4 + 4 * eax]

  167.     add edx,dword ptr [SumOfDigit4 + 4 * ebx]

  168.     mov dword ptr [s], edx

  169.     mov eax, 1

  170.     xchg eax,dword ptr [Status.S + 4 * edx]

  171.     cmp eax, 1

  172.     je label1

  173.     call WriteResult;

  174. label1:

  175.     mov eax,dword ptr [Status.Delta]

  176.     mov ebx,dword ptr [Status.Delta + 4]

  177.     mov ecx,dword ptr [Status.Delta + 8]

  178.     mov edx,dword ptr [Status.Delta + 12]

  179.     add eax, 2

  180.     mov esi, eax

  181.     sub esi, TenPower

  182.     cmovnc eax, esi

  183.     cmc

  184.     adc ebx, 0

  185.     mov edi, ebx

  186.     sub edi, TenPower

  187.     cmovnc ebx, edi

  188.     cmc

  189.     adc ecx, 0

  190.     mov esi, ecx

  191.     sub esi, TenPower

  192.     cmovnc ecx, esi

  193.     cmc

  194.     adc edx, 0

  195.     mov dword ptr [Status.Delta], eax

  196.     mov dword ptr [Status.Delta + 4], ebx

  197.     mov dword ptr [Status.Delta + 8], ecx

  198.     mov dword ptr [Status.Delta + 12], edx

  199.     inc dword ptr [Counter]

  200.     jne Label0

  201.     call WriteStatus

  202.     jmp label0

  203.   end;

  204. end.                                               
复制代码
下面是三个我编译的程序
GxQ运行下,因为有中断运行后自动恢复机制,要在不同目录运行,运行到产生157的地方停止
帮我看下在你机器上的时间信息

1.tar.bz2 (47.79 KB, 下载次数: 3)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-31 10:21:25 | 显示全部楼层
对不起,我不会用Pasal。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-31 11:14:07 | 显示全部楼层
编译好了的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-18 05:50 , Processed in 0.044072 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表