云计算基础实验

news2025/1/5 18:27:25

云计算基础实验报告

实验一 Linux环境下算法的测试

一, 根据基本计算思想,验证和求解,设计算法。

根据运行需要,自行完成(C和Python)环境配置。

1.1验证卡布列克常数6174

原理过程:

  1. 循环输入一个1000-9999之间的数字,找出其最大数和其最小数,并进行相减。直到其最后值得到6174.

  2. 输出此卡布列克常数的运算过程以及结果


算法实现(在C语言环境运行)

#include<stdio.h>

void sort(int a[], int num)   //将数字按照从大到小的顺序排列
{
    int i, j, temp;
    for (i = 0; i < num; i++)
        for (j = i + 1; j < num; j++)
            if (a[i] > a[j])
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
}

int main() {
    int n = 1000, count, result, s;
    int a[4];   //存储一个4位数
    int max, min;   //存放最大值最小值

    printf("验证[1000-9999]卡布列克常数6174:");


    while (n <= 9999)
    {
        count = 1; result = 0;
        s = n;
        
        while (n != 6174 && result != 6174 && count <= 7)
        {
            a[0] = s % 10;			/*分别算出4位数,再将其存放在数组中*/
            a[1] = s / 10 % 10;
            a[2] = s / 100 % 10;
            a[3] = s / 1000;

            sort(a, 4);   //调用函数

            max = 1000 * a[3] + 100 * a[2] + 10 * a[1] + a[0]; //计算最大值
            min = 1000 * a[0] + 100 * a[1] + 10 * a[2] + a[3];//计算最小值

            printf("[%d] : %d - %d = %d\n", count, max, min, max - min);

            result = max - min;
            count++;    //统计进行了几次计算

            
            if (result == 6174 && count < 8)
            {
                printf("%d is the num.\n", n);
                printf("-----------------------\n");
            }

            
                  
            s = result; //将进行减的值赋给s,回到while循环判断
        }   

        n = n + 1;

    }
    return 0;
}

结果显示(运行截图)

在这里插入图片描述

1.2蒙特卡洛算法

原理过程:

定义一个常量NUM_POINTS,表示要生成的随机点的数量。

使用rand()函数生成随机点,并检查这些点是否落在单位圆内(即x^2 + y^2 <= 1)

每生成一个落在单位圆内的点,计数器inside_circle就增加1

计算并输出π的估计值。

算法实现(


在C语言环境运行)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_POINTS 1000000

int main() {
    int inside_circle = 0;
    double x, y;

    // 初始化随机数种子
    srand(time(NULL));

    // 生成NUM_POINTS个随机点
    for (int i = 0; i < NUM_POINTS; i++) {
        // 生成0到1之间的随机数作为x和y坐标
        x = (double)rand() / RAND_MAX;
        y = (double)rand() / RAND_MAX;

        // 检查点是否在单位圆内
        if (x * x + y * y <= 1.0) {
            inside_circle++;
        }
    }

    // 计算π的估计值
    double pi = 4.0 * inside_circle / NUM_POINTS;

    printf("估计的π值为: %.6f\n", pi);

    return 0;
}

结果显示(运行截图)
在这里插入图片描述

1.3冰雹猜想验证(验证范围1~100)

原理过程:

输入一个1-100之间的整数n,如果n为偶数,就将它变成n/2,如果除后变成奇数,则将它乘3加1,不断重复运算,经过有限步数后,是否可以得到1


算法实现(在C语言环境运行)

#include<stdio.h>
int main()
{
    int i,number,count=0;

    for(i=1; i<=100; i++)
    {
        number = i;
        printf("%d : ",number);
        while(number != 1)
        {
            if (number % 2 == 0)
            {
                number /= 2;
                printf("%d - ", number);
            }
            else
            {
                number = number * 3 + 1;
                printf("%d - ", number);
            }
            count++;
        }
        printf("共执行了%d步\n",count);  
}
return 0;
}

结果显示(运行截图)

在这里插入图片描述

1.4亲和数验证(验证范围1~10000)

原理过程:

如果整数A的全部因子(包括1,但不包括其本身)之和等于整数B,整数B的因子(包括1,但不包括其本身)之和等于整数A,则整数A与B称为亲密数。


算法实现(在C语言环境运行)

#include<stdio.h>
int main()
{
    int a=1, i=1;
    int j=1;
    for(a=1; a<=10000; a++)
    {
        int B = 0, A = 0;
        for(i=1; i<a; i++)
        {
            if(a%i==0)
                {
                    B = B + i;
                }
        }

        for(j=1; j<B; j++)
        {
            if(B%j == 0)
                {
                    A = A + j;
                }
        }

        if(A == a )
            {
                printf("%d和%d是亲和数\n",a,B);
            }
    }
    return 0;
}

结果显示(运行截图)
在这里插入图片描述

实验二 MPI分布式运行框架设计

一、 实验目的

设计运行框架,了解运行环境需求。

nfs的应用

mpi的安装和使用

mpi的环境测试

二、 实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

三、 基本步骤介绍:

3.1 构建四台计算节点

  1. 每个节点计算机的网络均采用NAT模式,构建一个内部的计算集群.
  2. 设置每个节点的hostname,依次是node01, node02, node03, node04。
  3. 根据上一步顺序,依次设置每个节点ip,范围(192.168.26.111~114)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

四台主机都需要进行此配置

在这里插入图片描述

3.2 构建四台计算节点之间互相免密钥访问(使用rsa方式生成)

在这里插入图片描述

#公钥和密钥都已生成

在这里插入图片描述
在这里插入图片描述

3.3 给四台主机安装nfs并实现永久挂载

  1. 四台节点,全部安装nfs及nfs-utils

//下载nfs

在这里插入图片描述

  1. node01节点作为运行主节点,启动并运行nfs服务程序,该程序随系统启动。

在这里插入图片描述

  1. node01节点作为运行主节点,提供挂载的目录资源。

挂载目录/var/mpi4.0/,如果没有此目录,则先创建,再修改配置文件提供挂载。

在这里插入图片描述

  1. 其余节点node02~04,实现永久挂载主节点node01的共享目录,并具有读写权限。

770:可读可写,

sync:共享目录同步文件,

no_root_squash:root权限设置**

//现永久挂载主机 node01节点的共享目录
在这里插入图片描述

///在node02-04客户端上安装nfs-common(客户端包)

在这里插入图片描述

///在node01上重启nfs服务器,在node02-04上挂载目录到node01实现目录共享

在这里插入图片描述

#mount:这是用来挂载文件系统的命令。

#-t nfs:这指定了文件系统的类型为NFS。

#-o nolock:这是挂载选项,nolock表示客户端不锁定文件,这可以提高性能,但可能不适合需要严格文件锁定的应用。

#192.168.26.111:/var/mpi4.0:这是NFS服务器的IP地址和要挂载的远程目录的路径。这里假设NFS服务器的IP地址是192.168.26.111,并且您想要挂载的目录是/var/mpi4.0。

/var/mp14.0:这是本地挂载点的路径,即您希望将远程目录挂载到本地的哪个位置。

在这里插入图片描述
在这里插入图片描述

//编辑配置文件实现永久挂载

3.4 在node01节点上安装mpi4.0

  1. 通过官方网站链接,下载mpi4.0源码包(四台主机都要安装)

https://www.mpich.org/static/downloads/4.0/mpich-4.0.tar.gz

在这里插入图片描述
编译安装mpi到/var/mpi4.0/(四台虚拟机都要执行)

解压缩文件包

//解压

在这里插入图片描述

//安装编译软件

在这里插入图片描述

a) 进入mpich解压目录,安装make

//绿色为可执行文件,蓝色为目录

在这里插入图片描述

b) 设置安装目录(以下配置信息,仅供参考,未写完整,执行会有错误提示。请根据错误提示,修改正确)

**#./configure –disable-fortran --prefix=/**var/mpi4.0

**报错:**configure: error: The Fortran compiler gfortran does not accept programs that call the same

#–disable-fortran:告诉配置脚本在编译过程中不使用Fortran编译器支持。

–prefix=/var/mpi4.0**:** 指定了软件安装的前缀路径,软件将被安装到**/var/mpi4.0****目录下,所有相关的可执行文件、库文件、头文件等都将被放置在这个目录及其子目录中。**

在这里插入图片描述

**//**配置安装成功

在这里插入图片描述

c) make编译

在这里插入图片描述

d) make install 安装
在这里插入图片描述

#赋值放置程序的文件夹到共享目录/var/mpi4.0
在这里插入图片描述
在这里插入图片描述

#安装mpich

在这里插入图片描述

#切换到daisy用户(因为你如果用root用户编译运行程序,会导致权限过大)

在这里插入图片描述

#使用6个进程执行./cpi(下面显示运行结果和运行时间)

在这里插入图片描述

e) 退出到用户的主目录

#cd

f) 通过编辑.bashrc文件修改环境变量(每次打开终端时都会加载的启动项)

vim .bashrc

在这里插入图片描述

g) 测试环境变量设置

#source ~/.bashrc

#which mpicc 查看位置信息

#which mpiexec

在这里插入图片描述

h) 在/var/mpi4.0/examples下,创建主机名称集合文件csmpd.hosts,

vim csmpd.hosts

文件内容如下:

在这里插入图片描述

3.5环境测试

  1. 测试运行MPICH的例子程序

查询如何编译mpi源代码,如何运行mpi程序

  1. 例子程序运行截图

#rank是你返回的进程号

#size就是进程数

在这里插入图片描述

四、 Helloworld程序代码实现及测试展示:

4.1程序源码:

/*hello.c*/
#include <stdio.h>
#include "mpi.h"

int main( int argc, char *argv[] )
{
    int rank;
    int size;

    MPI_Init( 0, 0 );
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    printf( "Hello world from process %d of %d\n", rank, size );
    MPI_Finalize();
    return 0;
}

4.2程序编译输出文件

$mpicc –o hello hello.c

在这里插入图片描述

4.3运行

$mpiexec –n <processes> ./hello

$mpiexec -f csmpd.hosts –n <processes> ./hello

【截图显示】

在这里插入图片描述

实验三 基本MPI环境的程序测试

一、 实验目的

逐一测试,提供的mpi实验程序文件。

熟悉 MPI 编程,加深对其编程的理解。

二、实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

三、代码测试与截图

3.1代码来源程序5.4

具体代码如下:

/*文件名:who.c*/
#include "mpi.h"
#include <stdio.h>
int main(int argc,char **argv)
{
  	int myid, numprocs;
  	int namelen;
  	char processor_name[MPI_MAX_PROCESSOR_NAME];
  	MPI_Init(&argc,&argv);
  	MPI_Comm_rank(MPI_COMM_WORLD,&myid);//获得本进程ID
  	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);//获得总的进程数目
  	MPI_Get_processor_name(processor_name,&namelen);//获得本进程的机器名
  	printf("Hello World! Process %d of %d on %s\n",myid, numprocs, processor_name);
  	MPI_Finalize();
}

结果显示(运行截图)

在这里插入图片描述

3.2代码来源程序5.5

具体代码如下:

/*文件名:message.c*/
#include <stdio.h>
#include "mpi.h"
#include <string.h>
int main(int argc, char** argv)
{
     int myid,numprocs,source;
     MPI_Status status;
     char message[100];
     MPI_Init(&argc,&argv);
     MPI_Comm_rank(MPI_COMM_WORLD, &myid);
     MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
     if (myid != 0)
     {
           strcpy(message, "Hello World!");//为发送字符串赋值
           //发送字符串时长度要加1,从而包括串结束标志
           MPI_Send(message,strlen(message)+1, MPI_CHAR, 0,99,MPI_COMM_WORLD);
     }
     else
     {
           //除0进程的其他进程接收来自于0进程的字符串数据
           for (source = 1; source < numprocs; source++)
          {
                 MPI_Recv(message, 100, MPI_CHAR, source, 99,MPI_COMM_WORLD, &status);
                 printf("I am process %d. I recv string '%s' from process %d.\n", myid, message,source);
          }
     }
     MPI_Finalize();
}

结果显示(运行截图)

在这里插入图片描述

3.3代码来源程序5.7

具体代码如下:

#define N 100000000
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"
int main(int argc, char** argv)
{
  int myid,numprocs;
  int i;
  double local=0.0;
  double inte,tmp=0.0,x;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
  srand((int)time(0));//设置随机数种子
/*各节点分别计算一部分积分值*/
/*以下代码在不同节点运行的结果不同*/
  for(i=myid;i<N;i=i+numprocs)
  {
    x=10.0*rand()/(RAND_MAX+1.0);//求函数值
    tmp=x*x/N;
    local=tmp+local;//各节点计算面积和
  }	
//计算总的面积和,得到积分值
  MPI_Reduce(&local,&inte,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  if(myid==0)
  {
    printf("The integal of x*x=%16.15f\n",inte);
  }
  MPI_Finalize();
}

结果显示(运行截图)

在这里插入图片描述

3.4代码来源程序5.8

具体代码如下:

  1. 初始化MPI****环境。
  2. 获取当前进程的ID (myid) 和总进程数 (numprocs)****。
  3. 使用随机数生成器生成 N*N* 个在 [1, 10] 区间内的随机数 x*x*****。
  4. 计算每个随机数 x*x* 对应的 x2*x*2 并累加到 local 变量中。
  5. 调用自定义的归约函数 Myreduce**,将所有进程的 local** 值汇总到根节点(进程0**)。**
  6. 如果当前进程是根节点,打印出积分结果。
  7. 结束MPI****环境。
/*文件名 myreduce.c*/
#define N 100000000
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"

void Myreduce(double sendbuf, double *recvbuf, int root); // 修改函数原型

int main(int argc, char** argv) {
    int myid, numprocs;
    double local = 0.0;
    double inte;
    double x;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    // 采用归约对y=x*x在[1,10]区间求积分
    srand((unsigned)time(NULL) + myid); // 使用myid作为种子的一部分
    int localN = N / numprocs; // 每个进程处理的随机数数量
    for (int i = 0; i < localN; i++) {
        x = 10.0 * rand() / (RAND_MAX / 10.0 + 1.0); // 生成[1,10]区间的随机数
        local += x * x / N; // 累加到local变量中
    }
    Myreduce(local, &inte, 0); // 调用自定义的规约函数,传递local的值

    if (myid == 0) {
        printf("id:%d 总进程:%d The integral of x*x = %16.15f\n",myid,numprocs,inte);
    }
    MPI_Finalize();
    return 0;
}

// 自定义的归约函数
void Myreduce(double sendbuf, double *recvbuf, int root) {
    MPI_Status status;
    int myid, numprocs;
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    // 非root节点向root节点发送数据
    if (myid != root) {
        MPI_Send(&sendbuf, 1, MPI_DOUBLE, root, 99, MPI_COMM_WORLD);
    } else {
        *recvbuf = 0.0; // 初始化接收缓冲区
        // root节点接收数据并对数据求和,完成规约操作
        for (int i = 0; i < numprocs; i++) {
            if (i != root) {
                double tmp;
                MPI_Recv(&tmp, 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status);
                *recvbuf += tmp; // 累加求和
            }
        }
    }
}

结果显示(运行截图)

在这里插入图片描述

实验四 卡布列克常数的MPI测试

一、 实验题目

用 MPI 方式遍历数据,证明卡布列克常数6174猜想。

二、实验目的

熟悉 MPI 编程,加深对其编程的理解。

三、实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

四、原理介绍:

6174猜想:一个任意的四位正整数(全相同的除外,如1111)。将数字重新组合成一个最大的数和最小的数相减,重复这个过程,最多七步,必得6174。

例如:

输入:2000

输出:

第1步:2000-0002=1998

第2步:9981-1899=8082

第3步:8820-0288=8532

第4步:8532-2358=6174

分步解题:

  1. 遍历所有的四位数,判断。
  2. 分解数字的千位,百位,十位,个位,放置在4个变量中,排序,将最大的放在最前面,最小的放在最后面。
  3. 利用4个变量的值,构建四位数,最大值及最小值,并计算差值
  4. 如差值不是6174,则重复步骤2.如果差值为6174,则程序打印输出最终结果,程序结束。

用各自节点划分计算的数据范围,分担计算任务。

例如,如果有4个节点机器,就将10009999****分成四个小范围,分给****4****个节点计算验证。如果有****3****个节点机器,就将****10009999分成三个小范围,分给3个节点计算验证。

五、 程序代码实现及测试:

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

//找出最大值和最小值
void sort_digits(int num, int *sorted, int *largest, int *smallest) {
    for (int i = 0; i < 4; ++i) {
        sorted[i] = num % 10;
        num /= 10;
    }
    // Sort the digits
    for (int i = 0; i < 3; ++i) {
        for (int j = i + 1; j < 4; ++j) {
            if (sorted[i] > sorted[j]) {
                int temp = sorted[i];
                sorted[i] = sorted[j];
                sorted[j] = temp;
            }
        }
    }
    //将排序好的数组数编排成最大的数和最小的数
    *largest = sorted[0] * 1000 + sorted[1] * 100 + sorted[2] * 10 + sorted[3];
    *smallest = sorted[3] * 1000 + sorted[2] * 100 + sorted[1] * 10 + sorted[0];
}

//检查是否能在7步以内得到6174,输出运行节点和步骤
void check_convergence(int num, int myid, char *hostname) {
    int steps = 0;
    int sorted[4], largest, smallest;
    printf("进程 %d: 数字 %d on %s\n",myid, num,hostname);
    while (num != 6174 && steps < 7) {
        sort_digits(num, sorted, &largest, &smallest);
        num = largest - smallest;
        steps++;
        printf("进程 %d: 第%d步: %d - %d = %d on %s\n", myid, steps, largest, smallest, num, hostname);
    }
    if (num == 6174) {
        printf("进程 %d: Convergence to 6174 after %d 步: %d - %d = 6174 on %s\n",myid, steps, largest, smallest,hostname);
    }
}

int main(int argc, char **argv) {
    int myid, numprocs;
    char hostname[256];
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    gethostname(hostname, sizeof(hostname));

    int start = 1000 + myid * (9999 / numprocs);
    int end = 1000 + (myid + 1) * (9999 / numprocs);
    if (myid == numprocs - 1) {
        end = 9999;
    }

    for (int i = start; i <= end; ++i) {
        if (i % 1111 != 0) { //不包含四位数都相同的数
            check_convergence(i, myid, hostname);
        }
    }

    MPI_Finalize();
    return 0;
}

在这里插入图片描述
在这里插入图片描述

实验五 基于蒙特卡洛算法求π值的MPI程序设计

一、 实验题目

用 MPI 技术计算π的值,运行代码参考程序5.6。

二、实验目的

熟悉 MPI 编程,加深对其编程的理解。

三、实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

四、程序代码实现及测试

/*文件名:mtpi.c*/
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // 包含 time.h 头文件

int main(int argc, char **argv) {
    int myid, numprocs;
    int namelen;
    long count = 1000000;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Status status;
    MPI_Init(&argc, &argv); // 初始化 MPI 环境
    MPI_Comm_rank(MPI_COMM_WORLD, &myid); // 得到当前进程的进程号
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs); // 得到通信域中的总进程数
    MPI_Get_processor_name(processor_name, &namelen); // 得到节点主机名称
    srand((int)time(0)); // 设置随机种子
    double y;
    double x;
    long m = 0, m1 = 0, i = 0;
    double pi = 0.0, n = 0.0;
    for (i = 0; i < count; i++) {
        x = (double)rand() / (double)RAND_MAX; // 得到0~1之间的随机数,x坐标
        y = (double)rand() / (double)RAND_MAX; // 得到0~1之间的随机数,y坐标
        if ((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5) < 0.25) // 判断产生的随机点坐标是否在圆内
            m++;
    }
    n = 4.0 * m / 1000000;
    printf("Process %d of %d on %s pi= %f\n", myid, numprocs, processor_name, n);
    if (myid != 0) { // 判断是否是主节点
        MPI_Send(&m, 1, MPI_LONG, 0, 1, MPI_COMM_WORLD); // 子节点向主节点传送结果
    } else {
        long p = m; // 主进程也参与计算,所以初始化 p 为 m
        // 分别接收来自于不同子节点的数据
        for (int source = 1; source < numprocs; source++) {
            MPI_Recv(&m1, 1, MPI_LONG, source, 1, MPI_COMM_WORLD, &status); // 主节点接收数据
            p += m1;
        }
        pi = 4.0 * p / (count * numprocs); // 汇总计算 pi 值
        printf("pi= %f\n", pi);
    }
    MPI_Finalize(); // 结束 MPI 环境
    return 0;
}

五、运行结果效果图

在这里插入图片描述

实验六 并行计算的综合设计

一、 实验题目

用 MPI 技术去验证角谷猜想,要求验证数据的范围尽可能的大。

二、实验目的

熟悉 MPI 编程,加深对其编程的理解。

三、实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

四、程序代码实现及测试

#include <stdio.h>
#include <mpi.h>

// 函数用于验证角谷猜想,并返回到达1所需的步骤数
int collatzSteps(int number) {
    int steps = 0;
    while (number != 1) {
        if (number % 2 == 0) {
            number /= 2;
        } else {
            number = number * 3 + 1;
        }
        steps++;
    }
    return steps;
}

int main(int argc, char** argv) {
    int rank, size;
    int start, end, step;
    int namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];

    MPI_Init(&argc, &argv); // 初始化MPI环境
    MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取进程总数
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程标识
    MPI_Get_processor_name(processor_name, &namelen); // 获取节点名称

    // 确定每个进程的起始和结束值
    int total_numbers = 100; // 总共需要计算的数
    start = rank * (total_numbers / size) + 1;
    if (rank == size - 1) {
        // 最后一个进程需要处理剩余的数
        end = total_numbers;
    } else {
        end = start + (total_numbers / size) - 1;
    }

    // 输出当前进程的编号和所在节点名称
    printf("Process %d is on %s\n", rank, processor_name);

    // 验证角谷猜想并输出结果
    for (int i = start; i <= end; i++) {
        step = collatzSteps(i);
        printf("%d 执行了 %d 步, 等于1 on %s\n",i, step,processor_name);
    }

    MPI_Finalize(); // 结束MPI环境
    return 0;
}

五、运行结果效果图
在这里插入图片描述

实验七 并行计算的综合设计

一、 实验题目

用 MPI 技术去验证亲和数组合的个数。

要求验证数据,程序运行时间大于20分钟以上。

二、实验目的

熟悉 MPI 编程,加深对其编程的理解。

三、实验环境

Ubuntu 22.04 (LTS),

VM环境下,网络架构NAT,

计算节点数:4个

四、程序代码实现及测试

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

// 函数用于计算一个数的约数之和
int sum_of_divisors(int n) {
    int sum = 0;
    for (int i = 1; i <= n / 2; i++) {
        if (n % i == 0) {
            sum += i;
        }
    }
    return sum;
}

// 主程序
int main(int argc, char** argv) {
    int rank, size;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int namelen;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Get_processor_name(processor_name, &namelen); // 获取进程所在的节点名称

    // 设置验证的上限值
    int limit = 10000;

    // 计算每个进程的起始和结束值
    int start = rank * (limit / size);
    int end = (rank + 1) * (limit / size) - 1;
    if (rank == size - 1) {
        end = limit;
    }

    // 寻找亲和数并输出结果
    for (int a = start; a <= end; a++) {
        int B = sum_of_divisors(a);
        int A = sum_of_divisors(B);
        if (A == a) {
            printf(" 进程 %d: 亲和数: %d and %d on %s\n", rank, a, B,processor_name);
        }
    }

    MPI_Finalize();
    return 0;
}

五、运行结果效果图

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

// 函数用于计算一个数的约数之和
int sum_of_divisors(int n) {
    int sum = 0;
    for (int i = 1; i <= n / 2; i++) {
        if (n % i == 0) {
            sum += i;
        }
    }
    return sum;
}

// 主程序
int main(int argc, char** argv) {
    int rank, size;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int namelen;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Get_processor_name(processor_name, &namelen); // 获取进程所在的节点名称

    // 设置验证的上限值
    int limit = 10000;

    // 计算每个进程的起始和结束值
    int start = rank * (limit / size);
    int end = (rank + 1) * (limit / size) - 1;
    if (rank == size - 1) {
        end = limit;
    }

    // 寻找亲和数并输出结果
    for (int a = start; a <= end; a++) {
        int B = sum_of_divisors(a);
        int A = sum_of_divisors(B);
        if (A == a) {
            printf(" 进程 %d: 亲和数: %d and %d on %s\n", rank, a, B,processor_name);
        }
    }

    MPI_Finalize();
    return 0;
}

五、运行结果效果图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268843.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

京东供应链创新与实践:应用数据驱动的库存选品和调拨算法提升履约效率

2024 年度总结系列 2024 年 10 月&#xff0c;京东零售供应链技术团队凭借其在库存选品与调拨技术上的创新与实践&#xff0c;荣获运筹与管理学领域的国际顶级奖项 Daniel H. Wagner Prize。本文为您介绍获奖背后的供应链技术创新和落地应用。 00 摘要 在电商行业中&#x…

按照人们阅读Excel习惯来格式化BigDecimal

1、环境/问题描述 使用springboot发送邮件(附件)的方式将月度报表发送给领导查阅&#xff0c;数据是准确的&#xff0c;领导基本满意。 就是对一些数字的格式化提出了改进建议&#xff0c;比如不要让大数字自动转为科学计数法、浮点数小数点后都是0就不要带出来&#xff0c;根…

软体机器人研究报告:设计方法、材料与驱动、感知与控制

软体机器人因其出色的可变形性和高适应性受到了广泛关注&#xff0c;这些特性使其在医疗、救援、探测等复杂场景中展现出独特的优势和巨大的应用潜力。研究人员对软体机器人的设计方法、材料与驱动技术、感知与控制策略等方面进行深入研究&#xff0c;取得了一系列成果。 本文汇…

医疗数仓业务数据采集与同步

业务数据采集与同步 业务采集组件配置业务数据同步概述数据同步策略选择数据同步工具概述1.1.4 全量表数据同步DataX配置文件生成全量表数据同步脚本增量表数据同步 MySQL - Maxwell - Kafka - Flume - HDFSMaxwell配置增量表首日全量同步 业务采集组件配置 Maxwell将业务采集到…

神经网络-VggNet

2014年VggNet被推出&#xff0c;获取了ILSVRC2014比赛分类项目的第二名&#xff0c;第一名是GoogleNet&#xff0c;该网络在下节介绍&#xff0c;本节主要介绍VggNet。 VggNet可以称为是一个家族&#xff0c;根据层数的不同包括了A、A-LRN、B、C、D等网络结构&#xff0c;其中…

计算机网络 (7)物理层下面的传输媒体

一、定义与位置 物理层是计算机网络体系结构的最低层&#xff0c;它位于传输媒体&#xff08;传输介质&#xff09;之上&#xff0c;主要作用是为数据链路层提供一个原始比特流的物理连接。这里的“比特流”是指数据以一个个0或1的二进制代码形式表示。物理层并不是特指某种传输…

敏捷开发中的自动化脚手架在 HarmonyOS 的应用

文章目录 前言什么是自动化脚手架工具构建自动化脚手架实战代码项目目录结构生成功能说明 示例代码生成功能说明 主工具类入口功能说明 如何运行脚手架工具总结参考资料 前言 在敏捷开发环境中&#xff0c;快速搭建项目结构是提升开发效率的关键。然而&#xff0c;手动配置开发…

VScode 格式化代码空格记录

点击 -> “文件” -> “首选项" -> “设置” -> 按下图操作&#xff1a; 怎么格式化代码空格&#xff0c;先看下&#xff1a; 保存代码后&#xff0c;这代码自动格式化发&#xff0c;如下图&#xff1a; 你可以试试看就即可

Python编程技术

设计目的 该项目框架Scrapy可以让我们平时所学的技术整合旨在帮助学习者提高Python编程技能并熟悉基本概念&#xff1a; 1. 学习基本概念&#xff1a;介绍Python的基本概念&#xff0c;如变量、数据类型、条件语句、循环等。 2. 掌握基本编程技巧&#xff1a;教授学生如何使…

《Java核心技术 卷II》流的创建

流的创建 Collection接口中stream方法可以将任何集合转换为一个流。 用静态Stream.of转化成数组。 Stream words Stream.of(contents.split("\\PL")); of方法具有可变长参数&#xff0c;可以构建具有任意数量的流。 使用Array.stream(array,from,to)可以用数组…

ESP32-CAM开发板入门 (下载示例程序)

ESP32-CAM开发板例程使用 1、准备工作1.1、硬件准备1.2、软件准备 2、选择示例程序并录入第一步 1、准备工作 1.1、硬件准备 1.2、软件准备 Arduino IDE &#xff1a; 编程与写入&#xff08;下载地址 https://www.arduino.cc/en/software&#xff09; 安装好后将软件设置到…

Cocos Creator 3.8.5 正式发布,更小更快更多平台!

在 Cocos Creator 3.8.5 版本中&#xff0c;我们做了新一轮的优化。 在加载速度、代码裁剪、平台增强等多方面做了优化&#xff0c;提升了开发者体验和游戏性能。 希望能够助 Cocos 开发者们的产品更上一层楼。 一、加载速度优化 1、WASM 模块延迟加载 在早期版本中&#xff0c…

HTML——30.视频引入

<head><meta charset"UTF-8"><title>视频引入</title></head><body><!--video:在网页中引入音频IE8以及之前版本不支持属性名和属性值一样&#xff0c;可以只写属性名src属性:指定视频文件路径&#xff0c;必须要有controls属…

T7 TensorFlow入门实战——咖啡豆识别

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、前期准备 1. 导入数据 # Import the required libraries import numpy as np import PIL,pathlib from PIL import Image import ma…

OpenHarmony源码编译后烧录镜像教程,RK3566鸿蒙开发板演示

本文介绍瑞芯微主板/开发板编译OpenHarmony源码后烧录镜像的教程&#xff0c;触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器&#xff0c;树莓派卡片电脑设计&#xff0c;支持开源鸿蒙OpenHarmony3.2-5.0系统&#xff0c;适合鸿蒙开发入门学习。 编译源码…

flask后端开发(3):html模板渲染

目录 渲染模板html模板获取路由参数 gitcode地址&#xff1a; https://gitcode.com/qq_43920838/flask_project.git 渲染模板 这样就能够通过html文件来渲染前端&#xff0c;而不是通过return了 html模板获取路由参数

SOME/IP 协议详解——序列化

文章目录 0. 概述1.基本数据序列化2.字符串序列化2.1 字符串通用规则2.2 固定长度字符串规则2.3 动态长度字符串规则 3.结构体序列化4. 带有标识符和可选成员的结构化数据类型5. 数组5.1 固定长度数组5.2 动态长度数组5.3 Enumeration&#xff08;枚举&#xff09;5.4 Bitfield…

HTML5实现好看的喜庆圣诞节网站源码

HTML5实现好看的喜庆圣诞节网站源码 前言一、设计来源1.1 主界面1.2 圣诞介绍界面1.3 圣诞象征界面1.4 圣诞活动界面1.5 圣诞热度界面1.6 圣诞纪念界面1.7 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的喜庆圣诞节网站源码&#xff0c;圣…

嵌入式开发中的机器人表情绘制

机器人的表情有两种&#xff0c;一种是贴图&#xff0c;一钟是调用图形API自绘。 贴图效果相对比较好&#xff0c;在存储空间大的情况下是可以采用的。 自绘比较麻烦&#xff0c;但在资源和空缺少的情况下&#xff0c;也是很有用的。而且自绘很容易通过调整参数加入随机效果&…

opencv实现KNN算法识别图片数字

KNN算法实现识别图片数字 目录 KNN算法实现识别图片数字图片基本情况图片数据 图片数字识别图片数据处理及预测其它数字图片正确率预测 图片基本情况 图片 数据 图片像素是2000x1000,即高&#xff08;行&#xff09;1000&#xff0c;宽&#xff08;列&#xff09;2000&#xf…