c语言和fortran并行程序入门(3)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文学习的是配置openmpi环境,并写出相应c语言和fortran程序,依然以函数的累加为例子。


一、配置openmpi

不多啰嗦,直接放网站
下载openmpi-4.1.4的地址
从上面地址下载压缩包后,按以下命令操作

tar -zxvf openmpi-4.1.4.tar.gz
cd openmpi-4.1.4
./configure  //本处会等待一段时间
make all	//本处也会等待一段时间
make install   //本处依然会等待一段时间

以上操作亲测有效,非常帅气,萌新们可以对着控制台拍摄视频,发送朋友圈,并配上文字,你是黑客啦!

接下来要测试你的openmp是否安装成功,按如下代码顺序执行

cd /openmpi-4.1.4/examples/
mpicc -o hello_c hello_c.c
mpirun hello_c

以上就是简单执行了个helloworld,如果执行成功说明安装成功。

二、程序设计

1.并行计算1~1000的3nn+2*n的累加,c语言版

代码如下(示例):

#include<stdio.h>  
#include"omp.h"  


void test()
{   
    int n=0;
    int i;
    for (i = 1; i < 1001; i++)
    {
        n = n+ 3*i*i+2*i;
    }
}

void main()
{
    float startTime = omp_get_wtime();
    int i;

#pragma omp parallel for num_threads(2)  
    for (i = 0; i < 80000; i++)
    {
        test();
    }
    float endTime = omp_get_wtime();
    printf("指定 2 个线程,执行时间: %f\n", endTime - startTime);
    startTime = endTime;


#pragma omp parallel for num_threads(4)  
    for (i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("指定 4 个线程,执行时间: %f\n", endTime - startTime);
    startTime = endTime;


#pragma omp parallel for num_threads(8)  
    for (i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("指定 8 个线程,执行时间: %f\n", endTime - startTime);
    startTime = endTime;


#pragma omp parallel for num_threads(12)  
    for (i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("指定 12 个线程,执行时间: %f\n", endTime - startTime);
    startTime = endTime;

    for (i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("不使用OpenMP多线程,执行时间: %f\n", endTime - startTime);
    startTime = endTime;

    system("pause");
}

可以看到openmp的结果都是用带井号的注释实现的

2.并行计算1~1000的3nn+2*n的累加,fortran语言版

代码如下(示例):

program main

include 'omp_lib.h'
integer N,M,i,c1,c2,c_rate
real(kind=8) t
N=1000
t=0.0

call system_clock(c1, c_rate)
!$OMP PARALLEL DO
do i=1,N
!$OMP CRITICAL
t=t+3*i*i+2*i;
!$OMP END CRITICAL
M=OMP_get_num_threads()
enddo
call system_clock(c2,c_rate)
time = c2-c1
write(*, "('t =  ', F20.5, ' running on ', I3, ' threads.')") t,M
write(*,*) 'time=',time
stop
end

上面的代码一开始编写的时候也遇到了bug,就是用并行计算,每次算的结果都是错误的,我怀疑是线程之间传信息的时候,因为通信问题导致一些数据的丢失,一般会丢失个百分之一的数据,丢的不算多,但是算错了就是算错了。
所以最后用
! O M P C R I T I C A L 和 ! OMP CRITICAL和 ! OMPCRITICAL!OMP END CRITICAL
把要求值的部分锁住了,也就是每一时刻只有一个线程可以访问这个变量t,这样可能带来许多效率的损失,实际上最好的方法应该是用归约实现。
但是我用归约实现代码的时候,它还是算不对,很奇怪。


总结

fortran作为上世纪五十年代的古老语言,它运行速度极快,在并行计算任务中具有得天独厚的优势。闯过编译原理和计算机组成原理的计算机学子啊,岂能被区区编程语言难倒?
要知道,智者不入爱河,愚者重蹈覆辙,寡王一路硕博,建设美丽祖国!
加油!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值