英特尔多核编程大赛优化报告.docx
- 文档编号:23216409
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:22
- 大小:24.15KB
英特尔多核编程大赛优化报告.docx
《英特尔多核编程大赛优化报告.docx》由会员分享,可在线阅读,更多相关《英特尔多核编程大赛优化报告.docx(22页珍藏版)》请在冰豆网上搜索。
英特尔多核编程大赛优化报告
英特尔多核编程大赛优化报告
蒋黎
首先要感谢CSDN和Intel为我们提供了这么好的学习机会。
在比赛的过程中,
我对多核体系有了更多的了解,对优化也有了更深的认识。
希望能多跟大家
讨论,共同进步。
我优化的最终结果:
单核:
0.562s(Celeron3.06G)
双核:
0.375s(AMDAthlon64X2Dual3800+)
为了方便阅读,我把优化报告分成了几个部分:
概要篇(简述优化思路和方法)
源码篇(最终版本的源码)
算法篇(分析主要的算法)
大赛公布的原始代码:
(组织者后来要求计算和输出精度到小数点后7位,这里的输出代码做了相应的调整。
)
//* compute the potential energy of a collection of */
//* particles interacting via pairwise potential */
#include
#include
#include
#include
#include
#define NPARTS 1000
#define NITER 201
#define DIMS 3
int rand( void );
int computePot(void);
void initPositions(void);
void updatePositions(void);
double r[DIMS][NPARTS];
double pot;
double distx, disty, distz, dist;
int main() {
int i;
clock_t start, stop;
initPositions();
updatePositions();
start=clock();
for( i=0; i pot = 0.0; computePot(); if (i%10 == 0) printf("%5d: Potential: %10.7f ", i, pot); updatePositions(); } stop=clock(); printf ("Seconds = %10.9f ",(double)(stop-start)/ CLOCKS_PER_SEC); } void initPositions() { int i, j; for( i=0; i for( j=0; j r[i][j] = 0.5 + ( (double) rand() / (double) RAND_MAX ); } void updatePositions() { int i, j; for( i=0; i for( j=0; j r[i][j] -= 0.5 + ( (double) rand() / (double) RAND_MAX ); } int computePot() { int i, j; for( i=0; i for( j=0; j distx = pow( (r[0][j] - r[0][i]), 2 ); disty = pow( (r[1][j] - r[1][i]), 2 ); distz = pow( (r[2][j] - r[2][i]), 2 ); dist = sqrt( distx + disty + distz ); pot += 1.0 / dist; } } return 0; } 代码执行时间 3.97秒 优化报告1-概要篇 最终优化版本运行时间: 单核: 0.562s(Celeron3.06G) 双核: 0.375s(AMDAthlon64X2Dual3800+2.01GHz) ////////////////////////////////////////////////////////////////// 优化步骤和执行时间 测试系统主要使用使用Celeron3.06G。 每一步优化后均使用VTune分析主要 函数的运行情况。 多核测试使用AMDAthlon64X2Dual3800+2.01GHz。 1原始代码(4.39s) 使用VS2005转化原始的工程文件,编译并运行。 用VTune分析,可以看出,性能主要损失在computePot函数以及其子函数上, 其中SQRT操作非常耗费时间。 2优化pow为mul(3.156s) 容易看到pow(x,2)等价于x*x。 乘法操作比pow要高效很多。 用VTune分析,发现computePot函数占用CPU降为19%。 3使用Intel编译器(2.734s) 转化工程文件,使用IntelC++编译器。 用VTune分析,发现computePot函数占用CPU为99.29%。 可以看出,SQRT等函 数都被computePot函数囊括在内了。 4使用SSE2指令优化关键运算(2.453s) 通过应用SSE2指令,把数据每四组一起进行并发的运算。 经检测,每四组进行运算和每两组进行运算效果差不多,这应该是因为FDIV 运算单元已经饱和的缘故。 时间主要耗费在SQRT和DIV上了。 用VTune分析, computePot函数占用CPU为99%。 5迭代运算1/sqrt(x)(0.875s) 使用RSQRTPS计算近似值,通过两次迭代求出精确值。 必须迭代两次,否则精 度不够。 用VTune分析,computePot函数占用CPU为98%。 6汇编优化(0.609s) 为减少内存读写次数,提高指令并发程度,使用汇编语言进行关键算法优化。 每次进行8组数据的运算(sum_rsqrt函数),不足8组的剩余数据单独计算 (sum_rsqrt_trailing函数)。 用VTune分析,computePot函数及子函数占用CPU约为98%。 7指令重排(0.578s) 优化主要针对sum_rsqrt函数。 通过调整指令的运算顺序,增加指令并发度。 每次调整都通过VTune查看sum_rsqrt函数的运行时间。 重排前,Clockticks 为575,重排后Clockticks为524。 8rand函数优化(0.562s) 自行实现rand函数,减少系统调用和线程同步的开销。 9双核测试(0.375s) 由于条件所限,使用AMDAthlon64X2Dual3800+作为测试CPU。 10多线程代码(0.375s) 自行实现的多线程代码,替代OpenMP。 优化报告2-源码篇 #include #include #include #include #include #include #include #defineNPARTS1000 #defineNITER201 #defineDIMS3 intrand(void); intcomputePot(void); voidinitPositions(void); voidupdatePositions(void); voidt_create(); voidt_destroy(); __declspec(align(16))doubler[DIMS][NPARTS]; doublepot; doubledistx,disty,distz,dist; intmain(){ inti; clock_tstart,stop; initPositions(); updatePositions(); t_create(); start=clock(); for(i=0;i pot=0.0; computePot(); if(i%10==0)printf("%5d: Potential: %10.3f\n",i,pot); updatePositions(); } stop=clock(); t_destroy(); printf("Seconds=%10.9f\n",(double)(stop-start)/CLOCKS_PER_SEC); getchar(); } staticunsignedq_rand_hold=1; inlineintq_rand() { return(((q_rand_hold=q_rand_hold*214013L+2531011L)>>16)&0x7fff); } constdoubleinv_rand_max=1.0/(double)RAND_MAX; voidinitPositions(){ inti,j; for(i=0;i for(j=0;j r[i][j]=0.5+((double)q_rand()*inv_rand_max); } __declspec(naked)voidupdatePositions_sse() { staticunsigneds_mul1=0x343FD; staticunsigneds_add1=0x269EC3; staticunsigneds_mul2=0xA9FC6809; staticunsigneds_add2=0x1E278E7A; staticdouble s_inv_max=inv_rand_max; staticdouble s_half=0.5; __asm { movd xmm0,[q_rand_hold] movd xmm2,[s_mul2] movd xmm6,[s_mul1] movss xmm1,xmm0 pmuludq xmm0,xmm6 pmuludq xmm1,xmm2 movd xmm3,[s_add2] movd xmm7,[s_add1] paddq xmm0,xmm7 paddq xmm1,xmm3 movddup xmm4,[s_half] xor edx,edx xor ecx,ecx movlhps xmm0,xmm1 movapd xmm7,[r+edx+ecx+16*0] movlhps xmm2,xmm2 movddup xmm1,[s_inv_max] movlhps xmm3,xmm3 jmp calc_start //xmm0rand_hold //xmm1inv_max //xmm2mul2 //xmm3add2 //xmm4half dim_loop: xor ecx,ecx align 16 sum_loop: pmuludq xmm0,xmm2 movapd xmm7,[r+edx+ecx+16*0] paddq xmm0,xmm3 calc_start: subpd xmm7,xmm4 pshufd xmm6,xmm0,0x08 pmuludq xmm0,xmm2 pslld xmm6,0x01 paddq xmm0,xmm3 psrld xmm6,0x11 pshufd xmm5,xmm0,0x08 cvtdq2pd xmm6,xmm6 pslld xmm5,0x01 mulpd xmm6,xmm1 psrld xmm5,0x11 subpd xmm7,xmm6 cvtdq2pd xmm5,xmm5 movapd xmm6,[r+edx+ecx+16*1] mulpd xmm5,xmm1 subpd xmm6,xmm4 movapd [r+edx+ecx+16*0],xmm7 subpd xmm6,xmm5 movapd [r+edx+ecx+16*1],xmm6 add ecx,8*4 cmp ecx,NPARTS*8 jl sum_loop add edx,NPARTS*8 cmp edx,NPARTS*8*3 jl dim_loop movhlps xmm0,xmm0 movd [q_rand_hold],xmm0 ret } } voidupdatePositions(){ updatePositions_sse(); return; inti,j; for(i=0;i for(j=0;j r[i][j]-=0.5+((double)q_rand()*inv_rand_max); } #include constlongt_piece_count=32; volatileHANDLE t_handle[32]; volatileHANDLE t_resume[32]; volatileHANDLE t_wait=0; volatilesize_t t_count=1; volatiledoublet_result[32]; volatilelong t_index=0; volatilelong t_ref=0; volatilebool t_stop=false; static__declspec(align(16))doublehalf_d[2]={-0.5f,-0.5f}; static__declspec(align(16))doublethree_d[2]={1.5f,1.5f}; static__declspec(align(16))floathalf_f[4]={-0.5f,-0.5f,-0.5f,-0.5f}; static__declspec(align(16))floatthree_f[4]={1.5f,1.5f,1.5f,1.5f}; __declspec(naked)voidsum_rsqrt(double*,size_tc,size_ti) { i;c; __asm { mov edx,[esp+12] mov ecx,[esp+8] lea eax,[r+edx*8] sub ecx,8 movddup xmm7,[eax+NPARTS*8*0] movapd xmm0,[r+NPARTS*8*0+ecx*8+16*0] movapd xmm1,[r+NPARTS*8*0+ecx*8+16*1] subpd xmm0,xmm7 movapd xmm2,[r+NPARTS*8*0+ecx*8+16*2] subpd xmm1,xmm7 mulpd xmm0,xmm0 movapd xmm3,[r+NPARTS*8*0+ecx*8+16*3] subpd xmm2,xmm7 mov edx,[esp+4]//dst align 16 loop_top: mulpd xmm1,xmm1 movapd xmm4,[r+NPARTS*8*1+ecx*8+16*0] subpd xmm3,xmm7 mulpd xmm2,xmm2 movddup xmm7,[eax+NPARTS*8*1] mulpd xmm3,xmm3 subpd xmm4,xmm7 movapd xmm5,[r+NPARTS*8*1+ecx*8+16*1] mulpd xmm4,xmm4 subpd xmm5,xmm7 movapd xmm6,[r+NPARTS*8*1+ecx*8+16*2] mulpd xmm5,xmm5 subpd xmm6,xmm7 addpd xmm0,xmm4 movapd xmm4,[r+NPARTS*8*1+ecx*8+16*3] mulpd xmm6,xmm6 subpd xmm4,xmm7 movddup xmm7,[eax+NPARTS*8*2] addpd xmm1,xmm5 movapd xmm5,[r+NPARTS*8*2+ecx*8+16*0] mulpd xmm4,xmm4 subpd xmm5,xmm7 addpd xmm2,xmm6 movapd xmm6,[r+NPARTS*8*2+ecx*8+16*1] mulpd xmm5,xmm5 subpd xmm6,xmm7 addpd xmm3,xmm4 movapd xmm4,[r+NPARTS*8*2+ecx*8+16*2] mulpd xmm6,xmm6 subpd xmm4,xmm7 addpd xmm0,xmm5 movapd xmm5,[r+NPARTS*8*2+ecx*8+16*3] mulpd xmm4,xmm4 addpd xmm1,xmm6 movddup xmm6,[half_d] subpd xmm5,xmm7 cvtpd2ps xmm7,xmm0 sub ecx,8 mulpd xmm0,xmm6 mulpd xmm5,xmm5 addpd xmm2,xmm4 cvtpd2ps xmm4,xmm1 mulpd xmm1,xmm6 addpd xmm3,xmm5 movapd [edx+16],xmm0 cvtpd2ps xmm5,xmm2 mulpd xmm2,xmm6 movlhps xmm4,xmm7 movddup xmm0,[half_f] cvtpd2ps xmm7,xmm3 mulpd xmm3,xmm6 movlhps xmm5,xmm7
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 英特尔 多核 编程 大赛 优化 报告