⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft.c

📁 多核(64核)系统的并行FFT运算程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  { 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 + -