频道栏目
首页 > 资讯 > 其他 > 正文

MPI快速并行方阵和向量乘积+多机测试

18-01-23        来源:[db:作者]  
收藏   我要投稿

简述

之前使用的是在一台机器上的,内存非常有限,而核心数也不是很多,为了减小机器承受的压力,每运行到某块*alloc出的内存必定不被使用时,就立即free掉,而在多机上,这样的压力分散到了多台机器上。按照这次作业的要求,需要让计算速度尽可能快,这样就应当能不free的尽量不free,能不同步的不做同步,从而快速得到结果,再去free申请来的内存。

程序中还有一些细节,如当j=0时,操作row_now[j]必定会比操作row_now[0]慢,因为对j的取值解析也需要一次访问内存,为了至高的速度考虑,程序中应尽量避免这样的浪费。

上次课时,何老师指出,不必要的calloc也是一种浪费,因为对内存的清空,即初始化全0,也是要耗费时间的。在个问题中这样做是冗余的,因此只需要在j=0时对其做赋值,而其它时候做+=操作。

另外,如果在for循环中只对游标等于某个数值时做if判断,是非常不值得的,因为if的条件判断也是要耗费时间的,所以这部分被我重构了。

代码

注释中,用old:标注的是之前的做法和考虑,new:标注是新的做法和考虑。

/*
15121856 刘知昊
第2次作业(方阵x向量按行分配,计时)
 */
#include
#include
#include
#include

//方阵的维度
#define N 960000

time_t start,end;//开始和结束时间

int main()
{
    int *vec=NULL;//列向量
    //double *mat=NULL;//自己进程的那部分矩阵
    int my_rank;//自己进程的进程号
    int comm_sz;//总的进程数目
    int my_row;//本进程处理的行数
    int i,j;//通用游标
    double *result=NULL;//用来存本进程计算出的结果向量
    double *all_rst=NULL;//只给0号进程存总的结果
    double *row_now=NULL;//每个进程每次仅申请的一行

    /**********************/
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);

    //计时开始
    if(my_rank==0)
    {
        start=time(NULL);
    }

    //本进程处理的行数就是总阶数/进程数
    my_row=N/comm_sz;

    //为每个进程都申请空间
    vec=malloc(N*sizeof(int));
    //mat=malloc(N*my_row*sizeof(double));//这是个进程每次申请完
    row_now=malloc(N*sizeof(double));//这是每个进程每次仅申请一行
    result=malloc(my_row*sizeof(double));//old:为了初始值置0而使用calloc
    //new:为了效率而用malloc,只要在i=0时做赋值

    //向量的值的设定,使用memset会报错
    for(j=0;j<n;j++) vec[j]="1;" 本行的值的设定="" 在实际使用时,这里是读入本进程应处理的下一行="" for(j="0;j

测试

因为有其他同学也在用,他们在做什么事会直接影响我测试出的时间,在4主机48进程下测试了三次,时间的单位是秒: 这里写图片描述

这里写图片描述

这里写图片描述 我试过,如果直接把上一次(没有做速度上的优化时)的代码-O3编译,然后4主机48进程下跑(也就是说单纯依赖核心数的增加,而不对代码做速度上的优化)时,这个时间是380秒左右,相比之下,依赖重构在速度上优化了一半左右的时间。

当然,对速度的追求,造成了内存的浪费。如果真的有OPT算法,那么内存的浪费也完全没有了(可惜只能想想)。

相关TAG标签
上一篇:SpringCloud教程 | 五.断路器(hystrix)
下一篇:乐视网与乐视控股互掐:贾跃亭到底欠了多少亿?
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站