找回密码
 欢迎注册
楼主: 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. uses SysUtils;
  3. const
  4. TenPower = 10000;
  5. StatusFileName = 'Square.Status';
  6. LogFileName = 'Square.Log';
  7. BlockSize = 8;
  8. BoolSize = 320;
  9. type
  10. TStatus = record
  11. S:array[0..BoolSize - 1] of integer;
  12. SquareValue:array[0..BlockSize - 1] of integer;
  13. Delta:array[0..BlockSize - 1] of integer;
  14. end;
  15. var
  16. Status:TStatus;
  17. StatusFile: File of TStatus;
  18. LogFile:TextFile;
  19. SumOfDigit4: array[0..TenPower - 1] of integer;
  20. ExeFilePath: string;
  21. Counter:Integer;
  22. s: integer;
  23. procedure WriteLog (s:string);
  24. begin
  25. Assign (LogFile, ExeFilePath + LogFileName);
  26. if FileExists(ExeFilePath + LogFileName) then
  27. Append (LogFile)
  28. else
  29. Rewrite (LogFile);
  30. writeln (LogFile, s);
  31. Close (LogFile);
  32. end;
  33. procedure InitStatus;
  34. var
  35. i:integer;
  36. begin
  37. for I := 0 to BoolSize - 1 do
  38. Status.s[i]:= 0;
  39. for i := 0 to BlockSize - 1 do
  40. begin
  41. status.SquareValue[i]:= 0;
  42. status.delta[i]:= 0;
  43. end;
  44. Status.Delta[0]:= 1;
  45. end;
  46. procedure ReadStatus;
  47. begin
  48. Assign (StatusFile, ExeFilePath + StatusFileName);
  49. if FileExists(ExeFilePath + StatusFileName) then
  50. begin
  51. Reset (StatusFile);
  52. Read (StatusFile, Status);
  53. Close (StatusFile);
  54. end
  55. else
  56. InitStatus;
  57. end;
  58. procedure WriteStatus;
  59. begin
  60. Assign (StatusFile, ExeFilePath + StatusFileName);
  61. Rewrite (StatusFile);
  62. Write (StatusFile, Status);
  63. Close (StatusFile);
  64. end;
  65. procedure InitSumOfDigit4;
  66. var
  67. i3, i2, i1, i0, k:integer;
  68. begin
  69. k:= 0;
  70. for I3 := 0 to 9 do
  71. for I2 := 0 to 9 do
  72. for I1 := 0 to 9 do
  73. for I0 := 0 to 9 do
  74. begin
  75. SumOfDigit4[k]:= i3 + i2 + i1 + i0;
  76. INC (k);
  77. end;
  78. end;
  79. procedure WriteResult;
  80. var
  81. Str:String[128];
  82. i:integer;
  83. begin
  84. Str:= '';
  85. for i := BlockSize-1 downto 0 do
  86. if Status.SquareValue[i] > 0 then
  87. Str:= str + Format ('%4d', [Status.SquareValue[i]]);
  88. writeln (DateTimeToStr (now) + ': ' + IntToStr (s) + ' ' + str);
  89. writelog (DateTimeToStr (now) + ': ' + IntToStr (s) + ' ' + str);
  90. end;
  91. label label0, label1;
  92. begin
  93. WriteLog ('程序启动: ' + DateTimeToStr (now));
  94. WriteLn ('程序启动: ' + DateTimeToStr (now));
  95. ExeFilePath:= ExtractFilePath (ParamStr(0));
  96. Counter:= 0;
  97. InitSumOfDigit4;
  98. ReadStatus;
  99. WriteLog ('初始化完成: ' + DateTimeToStr (now));
  100. WriteLn ('初始化完成: ' + DateTimeToStr (now));
  101. //ADDDelta
  102. asm
  103. label0:
  104. mov eax, dword ptr [Status.SquareValue]
  105. add eax,dword ptr [Status.Delta]
  106. mov ebx,dword ptr [Status.SquareValue + 4]
  107. add ebx,dword ptr [Status.Delta + 4]
  108. mov esi, eax
  109. sub esi, TenPower
  110. cmovnc eax, esi
  111. cmc
  112. adc ebx, 0
  113. mov edx,dword ptr [SumOfDigit4 + 4 * eax]
  114. mov dword ptr [Status.SquareValue], eax
  115. mov eax,dword ptr [Status.SquareValue + 8]
  116. add eax,dword ptr [Status.Delta + 8]
  117. mov edi, ebx
  118. sub edi, TenPower
  119. cmovnc ebx, edi
  120. cmc
  121. adc eax, 0
  122. mov dword ptr [Status.SquareValue + 4], ebx
  123. add edx,dword ptr [SumOfDigit4 + 4 * ebx]
  124. mov ebx,dword ptr [Status.SquareValue + 12]
  125. add ebx,dword ptr [Status.Delta + 12]
  126. mov esi, eax
  127. sub esi, TenPower
  128. cmovnc eax, esi
  129. cmc
  130. adc ebx, 0
  131. mov dword ptr [Status.SquareValue + 8], eax
  132. add edx,dword ptr [SumOfDigit4 + 4 * eax]
  133. mov eax,dword ptr [Status.SquareValue + 16]
  134. mov edi, ebx
  135. sub edi, TenPower
  136. cmovnc ebx, edi
  137. cmc
  138. adc eax, 0
  139. mov dword ptr [Status.SquareValue + 12], ebx
  140. add edx,dword ptr [SumOfDigit4 + 4 * ebx]
  141. mov ebx,dword ptr [Status.SquareValue + 20]
  142. mov esi, eax
  143. sub esi, TenPower
  144. cmovnc eax, esi
  145. cmc
  146. adc ebx, 0
  147. mov dword ptr [Status.SquareValue + 16], eax
  148. add edx,dword ptr [SumOfDigit4 + 4 * eax]
  149. mov eax,dword ptr [Status.SquareValue + 24]
  150. mov edi, ebx
  151. sub edi, TenPower
  152. cmovnc ebx, edi
  153. cmc
  154. adc eax, 0
  155. mov dword ptr [Status.SquareValue + 20], ebx
  156. add edx,dword ptr [SumOfDigit4 + 4 * ebx]
  157. mov ebx,dword ptr [Status.SquareValue + 28]
  158. mov esi, eax
  159. sub esi, TenPower
  160. cmovnc eax, esi
  161. cmc
  162. adc ebx, 0
  163. mov dword ptr [Status.SquareValue + 24], eax
  164. mov dword ptr [Status.SquareValue + 28], ebx
  165. add edx,dword ptr [SumOfDigit4 + 4 * eax]
  166. add edx,dword ptr [SumOfDigit4 + 4 * ebx]
  167. mov dword ptr [s], edx
  168. mov eax, 1
  169. xchg eax,dword ptr [Status.S + 4 * edx]
  170. cmp eax, 1
  171. je label1
  172. call WriteResult;
  173. label1:
  174. mov eax,dword ptr [Status.Delta]
  175. mov ebx,dword ptr [Status.Delta + 4]
  176. mov ecx,dword ptr [Status.Delta + 8]
  177. mov edx,dword ptr [Status.Delta + 12]
  178. add eax, 2
  179. mov esi, eax
  180. sub esi, TenPower
  181. cmovnc eax, esi
  182. cmc
  183. adc ebx, 0
  184. mov edi, ebx
  185. sub edi, TenPower
  186. cmovnc ebx, edi
  187. cmc
  188. adc ecx, 0
  189. mov esi, ecx
  190. sub esi, TenPower
  191. cmovnc ecx, esi
  192. cmc
  193. adc edx, 0
  194. mov dword ptr [Status.Delta], eax
  195. mov dword ptr [Status.Delta + 4], ebx
  196. mov dword ptr [Status.Delta + 8], ecx
  197. mov dword ptr [Status.Delta + 12], edx
  198. inc dword ptr [Counter]
  199. jne Label0
  200. call WriteStatus
  201. jmp label0
  202. end;
  203. 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-12-27 16:33 , Processed in 0.025014 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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