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

[分享] B计划之基本函数性能预览

[复制链接]
发表于 2008-5-7 14:46:08 | 显示全部楼层
你还没考虑SSE2的8路展开版本了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-7 14:48:58 | 显示全部楼层
另外,你没比较超过L2缓存大小的数据
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-7 15:58:45 | 显示全部楼层
SSE2 的版本使用循环展开提速不明显,我的版本在每个循环步使用2条movdqa指令,也就是说和A_Clear_R8一样,每个循环步处理 8个DWORD,你的那个版本每个循环步使用1条movdqa指令,但速度没有明显变化,SSE2指令的版本,movdqa 是瓶颈,循环控制所花的时间可以忽略不计。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-7 15:59:13 | 显示全部楼层
很大的内存块(超过L2cache)清零的优化,我暂时不考虑。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-7 16:13:40 | 显示全部楼层
movq呢? movdqa可能因为CPU数据总线是64位的,会有冲突 多几次movq看下效果如何?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-7 20:15:06 | 显示全部楼层
我对4#有疑问,具体自己检查 另外,你时间不要写这么多零好不好? 我眼睛不好,也数不过来 最后希望能看到你测试的源代码 还有,是否用了Intel编译器?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-8 10:07:36 | 显示全部楼层
1.好吧,容我将单位改为毫秒。 2.编译器使用VC6.0,如果使用intel编译器,他会将简单循环作4路展开,C语言版的函数和汇编语言的4路循环展开版本大致相当。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-8 17:53:33 | 显示全部楼层
说几个对你测试的问题 1、清零的速度还可以提升 我算过,每秒可达到2.5GB/s以上,我的机器不如你的, 但我测试清零速度似乎能达到2.0G以上,你的似乎达不到 2、加的时钟你P4上的三操作数C代码是6.0个时钟每双字,而我算我的是4.9,说明加法要改进一个时钟是很困难的,你的代码虽然是2^30进制,但应该和我的2^32进制不会存在明显的差异,因为你多的操作应该不会造成很明显的延时
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-8 22:46:29 | 显示全部楼层
这里给出测试代码,请检查我的测试方法是否科学。
  1. int main(int argc, char* argv[])
  2. {
  3. test_a_clear();
  4. test_a_copy();
  5. test_add();
  6. test_sub();
  7. test_neg();
  8. return 0;
  9. }
  10. void test_a_clear()
  11. {
  12. int n=8192;
  13. //createFolders();
  14. //test_clear_function(256);
  15. test_clear_speed( n,0);
  16. test_clear_speed( n,1);
  17. test_clear_speed( n,2);
  18. test_clear_speed( n,3);
  19. test_clear_speed( n,4);
  20. test_clear_speed( n,5);
  21. test_clear_speed( n,6);
  22. test_clear_speed( n,7);
  23. }
  24. void test_a_copy()
  25. {
  26. int n=8192;
  27. //createFolders();
  28. //test_copy_function(256);
  29. test_copy_speed(n,0,0);
  30. test_copy_speed(n,0,1);
  31. test_copy_speed(n,0,2);
  32. test_copy_speed(n,0,3);
  33. test_copy_speed(n,1,0);
  34. test_copy_speed(n,1,1);
  35. test_copy_speed(n,1,2);
  36. test_copy_speed(n,1,3);
  37. test_copy_speed(n,2,0);
  38. test_copy_speed(n,2,1);
  39. test_copy_speed(n,2,2);
  40. test_copy_speed(n,2,3);
  41. test_copy_speed(n,3,0);
  42. test_copy_speed(n,3,1);
  43. test_copy_speed(n,3,2);
  44. test_copy_speed(n,3,3);
  45. }
  46. void test_add()
  47. {
  48. test_add_function(1024);
  49. test_add_speed( 8192);
  50. }
  51. void test_sub()
  52. {
  53. test_sub_function(1024);
  54. test_sub_speed( 8192);
  55. }
  56. void test_neg()
  57. {
  58. test_neg_function(1024);
  59. test_neg_speed( 8192);
  60. }
  61. void test_clear_speed( int len,int align16_offset)
  62. {
  63. DWORD *pData= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  64. DWORD *pTest1= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  65. DWORD *pTest2= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  66. DWORD *pTest3= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  67. DWORD *pTest4= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  68. DWORD *pTest5= (DWORD *)malloc( (len+64)* sizeof(DWORD));
  69. DWORD *pBuff1=NULL;
  70. DWORD *pBuff2=NULL;
  71. DWORD *pBuff3=NULL;
  72. DWORD *pBuff4=NULL;
  73. DWORD *pBuff5=NULL;
  74. int count=0;
  75. double t1,t2,t3,t4,t5;
  76. double s_t1,s_t2,s_t3,s_t4,s_t5;
  77. MadeNum(pData,len+32);
  78. count=0;
  79. s_t1=0.00;
  80. s_t2=0.00;
  81. s_t3=0.00;
  82. s_t4=0.00;
  83. s_t5=0.00;
  84. DWORD tmp;
  85. tmp=(DWORD)pTest1;
  86. while ((tmp & 0x3f) !=0)
  87. tmp+=4;
  88. pBuff1=(DWORD *)tmp;
  89. //--------------
  90. tmp=(DWORD)pTest2;
  91. while ((tmp & 0x3f) !=0)
  92. tmp+=4;
  93. pBuff2=(DWORD *)tmp;
  94. //--------------
  95. tmp=(DWORD)pTest3;
  96. while ((tmp & 0x3f) !=0)
  97. tmp+=4;
  98. pBuff3=(DWORD *)tmp;
  99. //--------------
  100. tmp=(DWORD)pTest4;
  101. while ((tmp & 0x3f) !=0)
  102. tmp+=4;
  103. pBuff4=(DWORD *)tmp;
  104. tmp=(DWORD)pTest5;
  105. while ((tmp & 0x3f) !=0)
  106. tmp+=4;
  107. pBuff5=(DWORD *)tmp;
  108. pBuff1 += align16_offset;
  109. pBuff2 += align16_offset;
  110. pBuff3 += align16_offset;
  111. pBuff4 += align16_offset;
  112. pBuff5 += align16_offset;
  113. do
  114. {
  115. memcpy(pBuff1,pData,(len)*sizeof(DWORD));
  116. memcpy(pBuff2,pData,(len)*sizeof(DWORD));
  117. memcpy(pBuff3,pData,(len)*sizeof(DWORD));
  118. memcpy(pBuff4,pData,(len)*sizeof(DWORD));
  119. memcpy(pBuff5,pData,(len)*sizeof(DWORD));
  120. t1=currTime();
  121. memset(pBuff1,0,len*sizeof(DWORD));
  122. t1=currTime()-t1;
  123. s_t1+=t1;
  124. t2=currTime();
  125. A_Clear(pBuff2,len);
  126. t2=currTime()-t2;
  127. s_t2+=t2;
  128. t3=currTime();
  129. A_Clear_R8(pBuff3,len);
  130. t3=currTime()-t3;
  131. s_t3+=t3;
  132. t4=currTime();
  133. A_Clear_With_SSE2(pBuff4,len);
  134. t4=currTime()-t4;
  135. s_t4+=t4;
  136. t5=currTime();
  137. yaos_AsmMemZero0(pBuff5,len);
  138. t5=currTime()-t5;
  139. s_t5+=t5;
  140. count++;
  141. }while (s_t1<0.001);
  142. s_t1 /=count;
  143. s_t2 /=count;
  144. s_t3 /=count;
  145. s_t4 /=count;
  146. s_t5 /=count;
  147. printf("\n\nClear zero function speed test,length unit: DWORD, time unit: ms\n");
  148. printf("pBuff1=%x\t",(DWORD)pBuff1);
  149. printf("pBuff2=%x\t",(DWORD)pBuff2);
  150. printf("pBuff3=%x\t",(DWORD)pBuff3);
  151. printf("pBuff4=%x\t",(DWORD)pBuff4);
  152. printf("pBuff5=%x\t",(DWORD)pBuff5);
  153. printf("\nlength\taddress\tmemset\tA_Clean\tA_Clean_R8\tA_Clear_With_SSE2\tyaos_AsmMemZero0\n");
  154. printf("%d\t32X+%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\n",
  155. len,align16_offset*4,
  156. s_t1*1000,s_t2*1000,s_t3*1000,s_t4*1000,s_t5*1000);
  157. free(pData);
  158. free(pTest1);
  159. free(pTest2);
  160. free(pTest3);
  161. free(pTest4);
  162. free(pTest5);
  163. }
  164. void test_copy_speed( int len,int src_offset,int tag_offset)
  165. {
  166. DWORD *pData= (DWORD *)malloc( (len+32)* sizeof(DWORD));
  167. DWORD *pTest1= (DWORD *)malloc( (len+32)* sizeof(DWORD));
  168. DWORD *pTest2= (DWORD *)malloc( (len+32)* sizeof(DWORD));
  169. DWORD *pTest3= (DWORD *)malloc( (len+32)* sizeof(DWORD));
  170. DWORD *pTest4= (DWORD *)malloc( (len+32)* sizeof(DWORD));
  171. int i,j,count=0;
  172. double t,s_t1,s_t2,s_t3,s_t4;
  173. double min_t1,min_t2,min_t3,min_t4;
  174. DWORD *psrc;
  175. DWORD *ptag1;
  176. DWORD *ptag2;
  177. DWORD *ptag3;
  178. DWORD *ptag4;
  179. DWORD tmp;
  180. MadeNum(pData,len+32);
  181. count=1024;
  182. min_t1=min_t2=min_t3=min_t4=1000;
  183. tmp=(DWORD)pData;
  184. while ((tmp & 0x1f) !=0)
  185. tmp+=4;
  186. psrc=(DWORD *)tmp;
  187. //--------------
  188. tmp=(DWORD)pTest1;
  189. while ((tmp & 0x1f) !=0)
  190. tmp+=4;
  191. ptag1=(DWORD *)tmp;
  192. //--------------
  193. tmp=(DWORD)pTest2;
  194. while ((tmp & 0x1f) !=0)
  195. tmp+=4;
  196. ptag2=(DWORD *)tmp;
  197. //--------------
  198. tmp=(DWORD)pTest3;
  199. while ((tmp & 0x1f) !=0)
  200. tmp+=4;
  201. ptag3=(DWORD *)tmp;
  202. //--------------
  203. tmp=(DWORD)pTest4;
  204. while ((tmp & 0x1f) !=0)
  205. tmp+=4;
  206. ptag4=(DWORD *)tmp;
  207. for (i=0;i<8;i++)
  208. {
  209. t=currTime();
  210. for (j=0;j<count;j++)
  211. {
  212. memcpy(ptag1+tag_offset,psrc+src_offset,len*sizeof(DWORD));
  213. }
  214. s_t1=currTime()-t;
  215. s_t1 /=count;
  216. if (s_t1<min_t1)
  217. min_t1=s_t1;
  218. }
  219. for (i=0;i<8;i++)
  220. {
  221. t=currTime();
  222. for (j=0;j<count;j++)
  223. {
  224. A_Copy(ptag2+tag_offset,psrc+src_offset,len);
  225. }
  226. s_t2=currTime()-t;
  227. s_t2 /=count;
  228. if (s_t2<min_t2)
  229. min_t2=s_t2;
  230. }
  231. for (i=0;i<8;i++)
  232. {
  233. t=currTime();
  234. for (j=0;j<count;j++)
  235. {
  236. A_Copy_With_SSE2(ptag3+tag_offset,psrc+src_offset,len);
  237. }
  238. s_t3=currTime()-t;
  239. s_t3 /=count;
  240. if (s_t3<min_t3)
  241. min_t3=s_t3;
  242. }
  243. for (i=0;i<8;i++)
  244. {
  245. t=currTime();
  246. for (j=0;j<count;j++)
  247. {
  248. A_Copy_R8(ptag4+tag_offset,psrc+src_offset,len);
  249. }
  250. s_t4=currTime()-t;
  251. s_t4 /=count;
  252. if (s_t4<min_t4)
  253. min_t4=s_t4;
  254. }
  255. printf("\n\n4 copy function speed test,time unit: ms,length unint:DWORD\n");
  256. printf("length\tsource address\ttarget address\tmemcpy\tA_Copy\tA_Copy_With_SSE2\tA_Copy_R8\n");
  257. printf("%d\t16X+%d\t16X+%d\t%.6f\t%.6f\t%.6f\t%.6f\n",
  258. len,src_offset*4,tag_offset*4,
  259. min_t1*1000,min_t2*1000,min_t3*1000,min_t4*1000);
  260. free(pData);
  261. free(pTest1);
  262. free(pTest2);
  263. free(pTest3);
  264. free(pTest4);
  265. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-8 22:47:21 | 显示全部楼层
接楼上:
  1. void test_add_speed( int len)
  2. {
  3. DWORD *pData1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  4. DWORD *pData2= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  5. DWORD *pResult1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  6. DWORD *pResult2= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  7. DWORD *pResult3= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  8. DWORD *pResult4= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  9. DWORD *pResult5= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  10. int i,j,count=0;
  11. double t,s_t1,s_t2,s_t3,s_t4,s_t5;
  12. double min_t1,min_t2,min_t3,min_t4,min_t5;
  13. MadeNum(pData1,len+4);
  14. MadeNum(pData2,len+4);
  15. A_Copy(pResult1,pData1,len+4);
  16. A_Copy(pResult2,pData1,len+4);
  17. A_Copy(pResult3,pData1,len+4);
  18. count=1024;
  19. min_t1=min_t2=min_t3=min_t4=min_t5=1000;
  20. for (i=0;i<8;i++)
  21. {
  22. t=currTime();
  23. for (j=0;j<count;j++)
  24. {
  25. BIN_Add_C(pResult1,pData2,len);
  26. }
  27. s_t1=currTime()-t;
  28. s_t1 /=count;
  29. if (s_t1<min_t1)
  30. min_t1=s_t1;
  31. }
  32. for (i=0;i<8;i++)
  33. {
  34. t=currTime();
  35. for (j=0;j<count;j++)
  36. {
  37. BIN_Add(pResult2,pData2,len);
  38. }
  39. s_t2=currTime()-t;
  40. s_t2 /=count;
  41. if (s_t2<min_t2)
  42. min_t2=s_t2;
  43. }
  44. for (i=0;i<8;i++)
  45. {
  46. t=currTime();
  47. for (j=0;j<count;j++)
  48. {
  49. BIN_Add_4way_unroll(pResult3,pData2,len);
  50. }
  51. s_t3=currTime()-t;
  52. s_t3 /=count;
  53. if (s_t3<min_t3)
  54. min_t3=s_t3;
  55. }
  56. for (i=0;i<8;i++)
  57. {
  58. t=currTime();
  59. for (j=0;j<count;j++)
  60. {
  61. BIN_Add_3P_C(pResult4,pData1,pData2,len);
  62. }
  63. s_t4=currTime()-t;
  64. s_t4 /=count;
  65. if (s_t4<min_t4)
  66. min_t4=s_t4;
  67. }
  68. for (i=0;i<8;i++)
  69. {
  70. t=currTime();
  71. for (j=0;j<count;j++)
  72. {
  73. BIN_Add_3P_4way_unroll(pResult5,pData1,pData2,len);
  74. }
  75. s_t5=currTime()-t;
  76. s_t5 /=count;
  77. if (s_t5<min_t5)
  78. min_t5=s_t5;
  79. }
  80. printf("\n\n5 add function speed test,time unit: ms,length unint:DWORD\n");
  81. printf("length\tBIN_ADD_C\tBIN_Add\tBIN_Add_4way_unroll\tBIN_Add_3P_C\tBIN_Add_3P_4way_unroll\n");
  82. printf("%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\n",len,
  83. min_t1*1000,min_t2*1000,min_t3*1000,min_t4*1000,min_t5*1000);
  84. free(pData1);
  85. free(pData2);
  86. free(pResult1);
  87. free(pResult2);
  88. free(pResult3);
  89. free(pResult4);
  90. free(pResult5);
  91. }
  92. void test_sub_speed( int len)
  93. {
  94. DWORD *pData1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  95. DWORD *pData2= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  96. DWORD *pResult1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  97. DWORD *pResult2= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  98. DWORD *pResult3= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  99. DWORD *pResult4= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  100. DWORD *pResult5= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  101. int i,j,count=0;
  102. double t,s_t1,s_t2,s_t3,s_t4,s_t5;
  103. double min_t1,min_t2,min_t3,min_t4,min_t5;
  104. createFolders();
  105. MadeNum(pData1,len+4);
  106. MadeNum(pData2,len+4);
  107. A_Copy(pResult1,pData1,len+4);
  108. A_Copy(pResult2,pData1,len+4);
  109. A_Copy(pResult3,pData1,len+4);
  110. count=1024;
  111. min_t1=min_t2=min_t3=min_t4=min_t5=1000;
  112. for (i=0;i<8;i++)
  113. {
  114. t=currTime();
  115. for (j=0;j<count;j++)
  116. {
  117. BIN_Sub_C(pResult1,pData2,len);
  118. }
  119. s_t1=currTime()-t;
  120. s_t1 /=count;
  121. if (s_t1<min_t1)
  122. min_t1=s_t1;
  123. }
  124. for (i=0;i<8;i++)
  125. {
  126. t=currTime();
  127. for (j=0;j<count;j++)
  128. {
  129. BIN_Sub_C(pResult2,pData2,len);
  130. }
  131. s_t2=currTime()-t;
  132. s_t2 /=count;
  133. if (s_t2<min_t2)
  134. min_t2=s_t2;
  135. }
  136. for (i=0;i<8;i++)
  137. {
  138. t=currTime();
  139. for (j=0;j<count;j++)
  140. {
  141. BIN_Sub_4way_unroll(pResult3,pData2,len);
  142. }
  143. s_t3=currTime()-t;
  144. s_t3 /=count;
  145. if (s_t3<min_t3)
  146. min_t3=s_t3;
  147. }
  148. for (i=0;i<8;i++)
  149. {
  150. t=currTime();
  151. for (j=0;j<count;j++)
  152. {
  153. BIN_Sub_3P_C(pResult4,pData1,pData2,len);
  154. }
  155. s_t4=currTime()-t;
  156. s_t4 /=count;
  157. if (s_t4<min_t4)
  158. min_t4=s_t4;
  159. }
  160. for (i=0;i<8;i++)
  161. {
  162. t=currTime();
  163. for (j=0;j<count;j++)
  164. {
  165. BIN_Sub_3P_4way_unroll(pResult5,pData1,pData2,len);
  166. }
  167. s_t5=currTime()-t;
  168. s_t5 /=count;
  169. if (s_t5<min_t5)
  170. min_t5=s_t5;
  171. }
  172. printf("\n\n5sub function speed test,time unit: ms,length unint:DWORD\n");
  173. printf("length\tBIN_Sub_C\tBIN_Sub\tBIN_sub_4way_unroll\tBIN_sub_3P_C\tBIN_sub_3P_4way_unroll\n");
  174. printf("%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\n",
  175. len,min_t1*1000,min_t2*1000,min_t3*1000,min_t4*1000,min_t5*1000);
  176. free(pData1);
  177. free(pData2);
  178. free(pResult1);
  179. free(pResult2);
  180. free(pResult3);
  181. free(pResult4);
  182. free(pResult5);
  183. }
  184. void test_neg_speed( int len)
  185. {
  186. DWORD *pData1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  187. DWORD *pResult1= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  188. DWORD *pResult2= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  189. DWORD *pResult3= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  190. DWORD *pResult4= (DWORD *)malloc( (len+4)* sizeof(DWORD));
  191. int i,j,count=0;
  192. double t,s_t1,s_t2,s_t3,s_t4;
  193. double min_t1,min_t2,min_t3,min_t4;
  194. MadeNum(pData1,len+4);
  195. A_Copy(pResult1,pData1,len+4);
  196. A_Copy(pResult2,pData1,len+4);
  197. A_Copy(pResult3,pData1,len+4);
  198. A_Copy(pResult4,pData1,len+4);
  199. count=1024;
  200. min_t1=min_t2=min_t3=min_t4=1000;
  201. for (i=0;i<8;i++)
  202. {
  203. t=currTime();
  204. for (j=0;j<count;j++)
  205. {
  206. BIN_Negate(pResult1,len);
  207. }
  208. s_t1=currTime()-t;
  209. s_t1 /=count;
  210. if (s_t1<min_t1)
  211. min_t1=s_t1;
  212. }
  213. for (i=0;i<8;i++)
  214. {
  215. t=currTime();
  216. for (j=0;j<count;j++)
  217. {
  218. BIN_Negate_C(pResult2,len);
  219. }
  220. s_t2=currTime()-t;
  221. s_t2 /=count;
  222. if (s_t2<min_t2)
  223. min_t2=s_t2;
  224. }
  225. for (i=0;i<8;i++)
  226. {
  227. t=currTime();
  228. for (j=0;j<count;j++)
  229. {
  230. BIN_Negate_4way_unroll(pResult3,len);
  231. }
  232. s_t3=currTime()-t;
  233. s_t3 /=count;
  234. if (s_t3<min_t3)
  235. min_t3=s_t3;
  236. }
  237. for (i=0;i<8;i++)
  238. {
  239. t=currTime();
  240. for (j=0;j<count;j++)
  241. {
  242. BIN_Negate_SSE2(pResult4,len);
  243. }
  244. s_t4=currTime()-t;
  245. s_t4 /=count;
  246. if (s_t4<min_t4)
  247. min_t4=s_t4;
  248. }
  249. printf("\n\n4 neg function speed test,time unit: ms,length unint:DWORD\n");
  250. printf("length\tBIN_NEG\t\tBIN_NEG_C\tBIN_NEG_4way_unroll\tBIN_Negate_SSE2\n");
  251. printf("%d\t%.6f\t%.6f\t%.6f\t%.6f\n",len,
  252. min_t1*1000,min_t2*1000,min_t3*1000,min_t4*1000);
  253. free(pData1);
  254. free(pResult1);
  255. free(pResult2);
  256. free(pResult3);
  257. free(pResult4);
  258. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-22 00:47 , Processed in 0.026853 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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