Chinaunix首页 | 论坛 | 博客
  • 博客访问: 403538
  • 博文数量: 77
  • 博客积分: 3149
  • 博客等级: 中校
  • 技术积分: 828
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-25 11:48
文章存档

2012年(5)

2011年(2)

2010年(11)

2009年(44)

2008年(15)

我的朋友

分类: LINUX

2009-06-10 18:09:06

最近一直在研究并行计算,还没有真正实践过,下面是矩阵乘法很经典的一个例子。我把完整的过程和代码写在下面,供初学者参考,高手就不用看了,以免浪费时间。
 
 
 
(1)serial.c
#include
#include
#include
#include
#define N 800 //250
int main()
{
  struct timeval starttime,endtime;
          double timepast;
 int i,j,k,m;
 int a[N][N],b[N][N],c[N][N];
for(i=0;i{
 for(j=0;j {
  srand((unsigned int)time(NULL)); //产生随机数种子
     m=( rand() % 100);
  a[i][j]=b[i][j]=m;           //产生0-100的随机数,给矩阵A,B赋初始值
  
 }
}
gettimeofday(&starttime,NULL);
for(i=0;i{  for(j=0;j    {  c[i][j]=0;
       for(k=0;k       {
         c[i][j]+=a[i][k]*b[k][j];
       }
    }
}
gettimeofday(&endtime,NULL);
   timepast=((double)(endtime.tv_sec-starttime.tv_sec)*1000000+(double)(endtime.tv_usec-starttime.tv_usec))/1000000;
   printf("the whole processing time of the program is %lf seconds\n",timepast);
}
 
 
(2) parallel.c

#include

#include

#include

#include

#include

#define N   800 //250

 

int main()

{

 

int size,rank;

 struct timeval starttime,endtime;

 double timepast;

 

    int i,j,k,m;

    int a[N][N],b[N][N],c[N][N];

for(i=0;i    //这里也可以实现并行但为了便于测试性能所以在计算的时候才用并行

{

 for(j=0;j

 {

     srand((unsigned int)time(NULL)); //产生随机数种子

         m=( rand() % 100);                 //产生0100的随机数给矩阵AB赋初始值

     a[i][j]=b[i][j]=m;

 }

}

 

omp_set_num_threads(4);

 gettimeofday(&starttime,NULL);

 

//#pragma omp parallel for  shared(a,b,c) private(i,j,k) num_threads(4) //利用OpenMP静态调度static的方法实现并行

#pragma omp parallel for shared(a,b,c) private(i,j,k) schedule(static,4)

//利用OpenMP静态调度static的方法实现并行

//#pragma omp for schedule(static)

for(i=0;i

{  for(j=0;j

    {  c[i][j]=0;

       for(k=0;k          //先给矩阵C赋初始值0然后循环计算A矩阵的行和B矩阵的列叠加结果给C

       {

         c[i][j]+=a[i][k]*b[k][j];

 //rank= omp_get_thread_num();

 //size= omp_get_num_threads();

 //printf( "[i=%d][k=%d][j=%d] from  %d of %d\n", i,k,j,rank, size );

       }

    }

}

gettimeofday(&endtime,NULL);

        timepast=((double)(endtime.tv_sec-starttime.tv_sec)*1000000+(double)(endtime.tv_usec-starttime.tv_usec))/1000000;

          printf("the whole processing time of the program is %lf seconds\n",timepast);

 

 

}

 

 (3)编译

本人在fedora.unix-center.net以及T10000.unix-center.net反复作了实验,实验结果基本上跟预想的差不多。

T10000是solaries,编译命令如下:

CC -xopenmp -o parallel parallel.c

CC  -o serial  serial.c

 

fedora是linux,编译命令如下:

gcc -fopenmp -o parallel parallel.c

gcc  -o serial  serial.c

笔者在实验过程中,采取上面的编译方式发现并行比串行并没有加速多少,很是苦恼。后来与同事交谈过程中,他在编译时加了编译优化。

gcc -fopenmp -O3 -o parallel parallel.c

一下子加速了很多。

笔者在自己实验室环境下测试(4核),没有加优化选项也能加速明显。另外,在开始测试过程中,可能是程序问题,一直出现并行比串行还差,无论是小计算量还是大的计算量都是如此,后来把代码改了改(就是上面最后的样子)就ok了,具体没有研究到底是哪个地方写得有问题。

先这样吧,改天再深入研究。

 


 
阅读(6229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~