对于一个理工生来说,学会用计算机程序计算数学问题好像还挺重要的,那我今天就简单看看矩形积分法在一般的C语言编译器(以Dev为例)和并行程序中代码有什么区别。
算算这个积分:
思路
我们知道积分就是求一个区间内函数图像与x轴所围成的面积
根据矩形积分法,
dev代码
#include <stdio.h>
#define f(x) 4/(1+x*x)
#define N 1000000
void main()
{
int i;
double sum;
for(i=0; i<N; i++)
{
sum += f(1.0*i/N)/N;
}
printf("the final sum is %lf\n", sum);
return 0;
}
所以这么简单的几行字,当时课堂上老师问有没有人会用C语言算积分的时候,我居然不敢举手......为什么呢......
运行结果
并行程序代码
这个是有注释的:
#include <stdio.h>
#include <omp.h> //展开多线程所需
#define N 1000000
#define f(x) 4/(1+x*x)
void main()
{
double sum_local[5], sum;
omp_set_num_threads(5); //抓捕多线程
#pragma omp parallel
{
int i, myid;
/*在线程内设置私有变量,不会被其他线程干扰,一般只在线程内用到的变量就可以直接在线程内定义*/
myid = omp_get_thread_num(); //获得所在线程的编号;
#pragma omp for
/*是傻瓜式的把任务分配给线程,即平均分,比如10个总线程,1和2给第一个线程,3和4给第二个线程,以此类推*/
for(i=0; i<N; i++)
{
sum_local[myid] += f(i*1.0/N);
}
if(myid = 0) //习惯上0线程是主线程
{
/*对于并行代码来说,只有一部分这些重复的运算是可以并行计算的,因此最后算结果的时候还是要合并到主线程*/
for(i=0; i<5; i++)
{
sum += sum_local[i]/N;
}
printf(“the final sum is %lf\n”, sum);
}
}
Return 0;
}
这个是没有注释的:
#include <stdio.h>
#include <omp.h>
#define N 1000000
#define f(x) 4/(1+x*x)
void main()
{
double sum_local[5], sum;
omp_set_num_threads(5);
#pragma omp parallel
{
int i, myid;
myid = omp_get_thread_num();
#pragma omp for
for(i=0; i<N; i++)
{
sum_local[myid] += f(i*1.0/N);
}
if(myid = 0)
{
for(i=0; i<5; i++)
{
sum += sum_local[i]/N;
}
printf(“the final sum is %lf\n”, sum);
}
}
Return 0;
}
说一说开始学并行计算的这几周
刚开始是Xshell刚开始用,只能用键盘操作,略感不适,包括vim,也只能键盘控制,我只是个脑袋不太能记东西的小白
各种openmp操作,和并行多线程计算有关的参数,对简单的问题来说,多了好多行代码,嗯...对,多敲几次就会了,只是沙子进眼睛了,不是困了......
编译的过程也很不一样,编译也要另外敲一行指令,不能快捷键一键编译运行了QAQ
不过也是有好的地方的, 比如并行比串行运行速度快。比如终于自己写出来可以运行的代码的时候,喜极而泣~