深圳大学并行计算实验一简单矩阵乘法的OpenMP并行程序

本文介绍了如何使用OpenMP在Windows环境下编写并行矩阵乘法程序,通过实验对比了不同线程数下的串行和并行执行时间,以及加速比,以评估并行化的效率。
摘要由CSDN通过智能技术生成

一. 实验目的

1. 学会编写简单的OpenMP程序;

2. 掌握for编译制导语句;

3. 对并行程序进行简单的性能分析;

二. 实验环境

1. 硬件环境:64核CPU、128GB内存的SMP并行计算平台;

2 软件环境:Microsoft Visual Studio 2013;

3. 登录方式:通过远程桌面(mstsc)连接172.31.226.180或hpc.szu.edu.cn:805,用户名和初始密码都是自己的学号。

三. 实验内容

1. 用OpenMP编写两个n阶方阵a和b的并行相乘程序,结果存放在方阵c中,其中矩阵乘法部分用for编译制导语句实现并行化操作。为了验证计算结果的正确性,将矩阵乘法的串行计算结果存放在方阵d中,并比较是否与c相等。在下面写出完整的程序代码,并添加必要的注释。

#include <omp.h>

#include <stdlib.h>

#include <time.h>

#include <iostream>

using namespace std;

const int n = 1000;

double a[n][n], b[n][n], c[n][n], d[n][n];

double chuanxing[5], bingxing[5];//记录串行执行时间与并行执行时间

void main()

{

    for (int i = 0; i < n; i++)

        for (int j = 0; j < n; j++)

        {

            a[i][j] = rand() * 1.0 / RAND_MAX;

            b[i][j] = rand() * 1.0 / RAND_MAX;

        }



    int hthreads=1;//线程数变量

    for (int pi = 0;pi < 7;pi++) {//每次线程数*2,循环七次

        printf("线程数为%d时:\n", hthreads);

        for (int h = 0;h < 5;h++) {//每次循环五次

            clock_t start1 = clock();//记录串行执行时间起始

            for (int i = 0;i < n;i++) {//串行矩阵运算

                for (int j = 0;j < n;j++) {

                    for (int k = 0;k < n;k++)

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

                }

            }

            clock_t end1 = clock();





            omp_set_num_threads(hthreads);//设置并行线程数

            clock_t start = clock();//记录并行执行起始时间

            int i, j, k;

            //以下是并行域,共享变量为a,b,c数组,私有变量是i,j,k

            #pragma omp parallel shared(a,b,c) private(i,j,k)

            {

                #pragma omp for  //对以下for循环进行并行线程分配

                for (i = 0;i < n;i++) {

                    for (j = 0;j < n;j++) {

                        for (k = 0;k < n;k++) {

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

                        }

                    }

                }



            }

            clock_t end = clock();



            //打印结果,并计算所记录的时间、加速比

            printf("---------------------第%d次:----------------------\n", h+1);

            bingxing[h] = (end - start) / 1000.0;

            chuanxing[h] = (end1 - start1) / 1000.0;

            printf("串行消耗时间为:%f秒\n", chuanxing[h]);

            printf("并行消耗时间为:%f秒\n", bingxing[h]);

            printf("加速比为%f\n", chuanxing[h] / bingxing[h]);





            //遍历查看是否有不一致计算结果

            for (int i = 0;i < n;i++) {

                for (int j = 0;j < n;j++) {



                    if (c[i][j] != d[i][j])

                    {



                        printf("c[%d][%d]=%f,d[%d][%d]=%f ", i, j, c[i][j], i, j, d[i][j]);

                        printf("不相同\n");

                        exit(0);

                    }

                }

            }

        }

        //线程数*2

        hthreads *= 2;





        //遍历并计算串行、并行执行时间以及加速比的平均值

        double average[2] = { 0,0 };

        for (int i = 0;i < 5;i++) {

            average[0] += chuanxing[i];

            average[1] += bingxing[i];

        }

        average[0] /= 5.0;

        average[1] /= 5.0;

        printf("-------------------------------------------------\n");

        printf("串行平均时间为:%f秒\n", average[0]);

        printf("并行平均时间为:%f秒\n", average[1]);

        printf("平均加速比为%f\n", average[0] / average[1]);

        printf("-------------------------------------------------\n");



    }

}

2. 测试并行程序在不同线程数下的执行时间和加速比(串行执行时间/并行执行时间),并分析实验结果。其中,n固定为1000,线程数分别取1、2、4、8、16、32、64时,为减少误差,每项实验进行5次,取平均值作为实验结果。

表1 并行程序在不同线程数下的执行时间(秒)和加速比

线程数

执行时间

1

2

4

8

16

32

64

第1次

4.438

2.609

2.472

2.333

2.281

2.269

2.331

第2次

4.420

2.718

2.408

2.326

2.306

2.288

2.270

第3次

4.393

3.095

2.410

2.326

2.293

2.271

2.259

第4次

4.448

2.703

2.355

2.286

2.293

2.305

2.260

第5次

4.431

2.727

2.447

2.341

2.303

2.262

2.264

平均值

4.426

2.770

2.418

2.322

2.295

2.279

2.276

加速比

0.852

1.332

1.523

1.580

1.650

1.609

1.616

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值