📄 fft.c
字号:
{ pthread_mutex_init(&(Global->idlock), NULL);}; Global->id = 0; InitX(x); /* place random values in x *//************************************************************************************************//* 无需检验结果和打印数据,注释掉 if (test_result) { ck1 = CheckSum(x); } if (doprint) { printf("Original data values:\n"); PrintArray(N, x); }*//************************************************************************************************/ InitU(N,umain); /* initialize u arrays*/ InitU2(N,umain2,rootN); /* fire off P processes */ { long i, Error; for (i = 0; i < (P) - 1; i++) { Error = pthread_create(&PThreadTable[i], NULL, (void * (*)(void *))(SlaveStart), NULL);/*建立了(P-1)个进程,即把任务分配给P个处理器,线程建立成功后赋0值给Error*//************************************************************************************************//* 对线程是否建立进行判断,当出现未结束线程时打印错误报告,可忽略 if (Error != 0) { printf("Error in pthread_create().\n"); exit(-1); }*//************************************************************************************************/ } SlaveStart();/*调用SlaveStart函数*/}; { long i, Error; for (i = 0; i < (P) - 1; i++) { Error = pthread_join(PThreadTable[i], NULL);/*等待分配的进程全部结束,成功后赋0值给Error*//************************************************************************************************//* 判断是否所有子线程都结束,当出现未结束线程时打印错误报告,可忽略 if (Error != 0) { printf("Error in pthread_join().\n"); exit(-1); }*/ /************************************************************************************************/ }};/************************************************************************************************//* 打印FFT数据结果,注释掉 if (doprint) { if (test_result) { printf("Data values after inverse FFT:\n"); } else { printf("Data values after FFT:\n"); } PrintArray(N, x); }*//************************************************************************************************/ /*输出每个处理器的时间数据*/ transtime = Global->transtimes[0]; printf("\n"); printf(" PROCESS STATISTICS\n"); printf(" Computation Transpose Transpose\n"); printf(" Proc Time Time Fraction\n"); printf(" 0 %10ld %10ld %8.5f\n", Global->totaltimes[0],Global->transtimes[0], ((double)Global->transtimes[0])/Global->totaltimes[0]); if (dostats) { transtime2 = Global->transtimes[0]; avgtranstime = Global->transtimes[0]; avgcomptime = Global->totaltimes[0]; maxtotal = Global->totaltimes[0]; mintotal = Global->totaltimes[0]; maxfrac = ((double)Global->transtimes[0])/Global->totaltimes[0]; minfrac = ((double)Global->transtimes[0])/Global->totaltimes[0]; avgfractime = ((double)Global->transtimes[0])/Global->totaltimes[0]; for (i=1;i<P;i++) { if (Global->transtimes[i] > transtime) { transtime = Global->transtimes[i]; } if (Global->transtimes[i] < transtime2) { transtime2 = Global->transtimes[i]; } if (Global->totaltimes[i] > maxtotal) { maxtotal = Global->totaltimes[i]; } if (Global->totaltimes[i] < mintotal) { mintotal = Global->totaltimes[i]; } if (((double)Global->transtimes[i])/Global->totaltimes[i] > maxfrac) { maxfrac = ((double)Global->transtimes[i])/Global->totaltimes[i]; } if (((double)Global->transtimes[i])/Global->totaltimes[i] < minfrac) { minfrac = ((double)Global->transtimes[i])/Global->totaltimes[i]; } printf(" %3ld %10ld %10ld %8.5f\n", i,Global->totaltimes[i],Global->transtimes[i], ((double)Global->transtimes[i])/Global->totaltimes[i]); avgtranstime += Global->transtimes[i]; avgcomptime += Global->totaltimes[i]; avgfractime += ((double)Global->transtimes[i])/Global->totaltimes[i]; } printf(" Avg %10.0f %10.0f %8.5f\n", ((double) avgcomptime)/P,((double) avgtranstime)/P,avgfractime/P); printf(" Max %10ld %10ld %8.5f\n", maxtotal,transtime,maxfrac); printf(" Min %10ld %10ld %8.5f\n", mintotal,transtime2,minfrac);/*统计数据输出*/ } Global->starttime = start; printf("\n"); printf(" TIMING INFORMATION\n"); printf("Start time : %16lu\n", Global->starttime); printf("Initialization finish time : %16lu\n", Global->initdonetime); printf("Overall finish time : %16lu\n", Global->finishtime); printf("Total time with initialization : %16lu\n", Global->finishtime-Global->starttime); printf("Total time without initialization : %16lu\n", Global->finishtime-Global->initdonetime); printf("Overall transpose time : %16ld\n", transtime); printf("Overall transpose fraction : %16.5f\n", ((double) transtime)/(Global->finishtime-Global->initdonetime)); printf("\n");/************************************************************************************************/ /*结果正确性测试,可忽略 if (test_result) { ck3 = CheckSum(x); printf(" INVERSE FFT TEST RESULTS\n"); printf("Checksum difference is %.3f (%.3f, %.3f)\n", ck1-ck3, ck1, ck3); if (fabs(ck1-ck3) < 0.001) { printf("TEST PASSED\n"); } else { printf("TEST FAILED\n"); } } {exit(0);};*//************************************************************************************************/}/************************************************************************************************//*调用函数区域*//************************************************************************************************/void SlaveStart(){ long i; long MyNum; double *upriv; long initdone; long finish; long l_transtime=0; long MyFirst; long MyLast; {pthread_mutex_lock(&(Global->idlock));}; MyNum = Global->id; Global->id++; {pthread_mutex_unlock(&(Global->idlock));}; {;};/* POSSIBLE ENHANCEMENT: Here is where one might pin processes to processors to avoid migration */ { pthread_barrier_wait(&(Global->start));}; upriv = (double *) malloc(2*(rootN-1)*sizeof(double)); if (upriv == NULL) { fprintf(stderr,"Proc %ld could not malloc memory for upriv\n",MyNum); exit(-1); } for (i=0;i<2*(rootN-1);i++) { upriv[i] = umain[i]; } MyFirst = rootN*MyNum/P; MyLast = rootN*(MyNum+1)/P; TouchArray(x, trans, umain2, upriv, MyFirst, MyLast); { pthread_barrier_wait(&(Global->start));};/* POSSIBLE ENHANCEMENT: Here is where one might reset the statistics that one is measuring about the parallel execution */ if ((MyNum == 0) || (dostats)) { { struct timeval FullTime; gettimeofday(&FullTime, NULL); (initdone) = (unsigned long)(FullTime.tv_usec + FullTime.tv_sec * 1000000);}; } /* perform forward FFT */ FFT1D(1, M, N, x, trans, upriv, umain2, MyNum, &l_transtime, MyFirst, MyLast, pad_length, test_result, dostats); /* perform backward FFT */ if (test_result) { FFT1D(-1, M, N, x, trans, upriv, umain2, MyNum, &l_transtime, MyFirst, MyLast, pad_length, test_result, dostats); } if ((MyNum == 0) || (dostats)) { { struct timeval FullTime; gettimeofday(&FullTime, NULL); (finish) = (unsigned long)(FullTime.tv_usec + FullTime.tv_sec * 1000000);}; Global->transtimes[MyNum] = l_transtime; Global->totaltimes[MyNum] = finish-initdone; } if (MyNum == 0) { Global->finishtime = finish; Global->initdonetime = initdone; }}double TouchArray(double *x, double *scratch, double *u, double *upriv, long MyFirst, long MyLast){ long i,j,k; double tot = 0.0; /* touch my data */ for (j=0;j<2*(rootN-1);j++) { tot += upriv[j]; } for (j=MyFirst; j<MyLast; j++) { k = j * (rootN + pad_length); for (i=0;i<rootN;i++) { tot += x[2*(k+i)] + x[2*(k+i)+1] + scratch[2*(k+i)] + scratch[2*(k+i)+1] + u[2*(k+i)] + u[2*(k+i)+1]; } } return tot;}double CheckSum(double *x){ long i,j,k; double cks; cks = 0.0; for (j=0; j<rootN; j++) { k = j * (rootN + pad_length); for (i=0;i<rootN;i++) { cks += x[2*(k+i)] + x[2*(k+i)+1]; } } return(cks);}void InitX(double *x){ long i,j,k; srand48(0); for (j=0; j<rootN; j++) { k = j * (rootN + pad_length); for (i=0;i<rootN;i++) { x[2*(k+i)] = drand48(); x[2*(k+i)+1] = drand48(); } }}void InitU(long N, double *u){ long q; long j; long base; long n1; for (q=0; 1<<q<N; q++) { n1 = 1<<q; base = n1-1; for (j=0; j<n1; j++) { if (base+j > rootN-1) { return; } u[2*(base+j)] = cos(2.0*PI*j/(2*n1)); u[2*(base+j)+1] = -sin(2.0*PI*j/(2*n1)); } }}void InitU2(long N, double *u, long n1){ long i,j,k; for (j=0; j<n1; j++) { k = j*(rootN+pad_length); for (i=0; i<n1; i++) { u[2*(k+i)] = cos(2.0*PI*i*j/(N)); u[2*(k+i)+1] = -sin(2.0*PI*i*j/(N)); } }}long BitReverse(long M, long k){ long i; long j; long tmp; j = 0; tmp = k; for (i=0; i<M; i++) { j = 2*j + (tmp&0x1); tmp = tmp>>1; } return(j);}void FFT1D(long direction, long M, long N, double *x, double *scratch, double *upriv, double *umain2, long MyNum, long *l_transtime, long MyFirst, long MyLast, long pad_length, long test_result, long dostats){ long j; long m1; long n1; unsigned long clocktime1; unsigned long clocktime2; m1 = M/2; n1 = 1<<m1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -