深圳大学并行计算实验二寻找完数的OpenMP并行程序

本文介绍了如何使用OpenMP在64核CPU的并行计算平台上编写并行程序,求解小于等于5000000的完数。通过调整for循环的schedule参数,优化了执行时间,同时分析了不同线程数下的执行时间与加速比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 实验目的

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

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

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

二. 实验环境

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

2 软件环境:Microsoft Visual Studio 2013;

三. 实验内容

1. 用OpenMP语言编写程序,求小于等于n的所有完数(一个数恰好等于它的因子之和),并存放在数组a中,调节for编译制导语句中schedule的参数,使得执行时间最短。为了验证计算结果的正确性,将串行计算结果存放在数组b中,并比较是否与c相等。在下面写出完整的程序代码,并添加必要的注释。

#include <omp.h>

#include <stdlib.h>

#include <time.h>

#include <iostream>

using namespace std;

const int n = 5000000;

int b[5];

int number = 0, number2 = 0;

int c1, c2;

double chuanxing, bingxing[5];

bool judge(int p) {

    //判断变量 k

    int k = 1;

    //边界变量 max_p

    int max_p = (int)(sqrt(double(p)) + 1);

   

    for (int i = 2;< max_p;i++) {

        if (% i == 0) {

            k += i+p/i;

        }

    }

    if (== p) {

        return true;

    }

    else

        return false;

}

int main() {

    cout << "--------------------------------------串行计算---------------------------------" << endl;

    clock_t start1 = clock();

    for (int p = 2;<= n;p++) {

        if (judge(p)) {

            b[number] = p;

            number++;

            //cout << p << endl;

        }

    }

    clock_t end1 = clock();

    chuanxing = (end1 - start1) / 1000.0;

    cout << "串行消耗时间为:" << chuanxing << "" << endl;

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

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

        cout << "+++++++++++++++++++++++++++++++线程数为" << hthreads << "时:++++++++++++++++++++++++" << endl;

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

            int a[5];

            cout << "---------------------" << h + 1 << "次并行计算:----------------------" << endl;

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

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

            int i, j = 1, k = 0, p;

            //以下是并行域,共享变量为a,b数组,私有变量是i,j,p shared(b,a) private(i,p,j)

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

            {

                #pragma omp for  schedule(static,100)     //对以下for循环进行并行线程分配 调度任务块大小为100

                for (= 2;<= n;p++) {

                    int max_p = (int)(sqrt(double(p)) + 1);

                    for (= 2;< max_p;i++) {

                        if (% i == 0)

                            j += i + p / i;

                    }

                    if (== p) {

                        a[number2] = p;

                        //原子操作防止写入错误

                        #pragma omp atomic

                        number2++;

                        j = 1;

                    }

                    else

                        j = 1;

                }

               

            }

            clock_t end = clock();

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

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

            cout << "并行消耗时间为:" << bingxing[h] << "" << endl;

            cout << "加速比为" << chuanxing / bingxing[h] << endl;

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

            for (int i = 0, j = 0;< number, j < number2;i++, j++) {

                c1 += a[i];

                c2 += b[i];

               

            }

            if (c1!=c2)

            {

                cout << "number=" << number << " number2=" << number2 << endl;

                cout << "c1="<<c1<<" c2="<<c2 << endl;

                cout << "不相同" << endl;

                exit(0);

            }

        number2 = 0;

        }

        //线程数*2  

        hthreads *= 2;

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

        double average = { 0 };

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

            average += bingxing[i];

        }

        average /= 5.0;

        cout << "-----------------------------------------" << endl;

        cout << "并行平均时间为:" << average << "" << endl;

        cout << "平均加速比为" << chuanxing / average  << endl;

        cout << "-----------------------------------------" << endl;

    }

}

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

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

线程数

执行时间

1

2

4

8

16

32

64

第1次

27.646

16.545

16.906

12.552

11.953

11.427

11.4

第2次

27.724

16.517

16.581

12.345

11.973

11.402

11.278

第3次

27.698

17.019

16.589

12.339

11.91

11.906

11.449

第4次

27.798

17.391

17.228

12.646

12.064

12.019

11.577

第5次

27.657

19.385

14.939

12.523

11.977

11.628

10.898

平均值

27.705

17.371

16.449

12.481

11.976

11.676

11.320

加速比

0.913

1.456

1.538

2.03

2.113

2.167

2.235

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值