当前位置:文档之家› openMP实验总结报告

openMP实验总结报告

openMP实验报告目录openMP实验报告.............................................. 错误!未定义书签。

OpenMP简介.............................................. 错误!未定义书签。

实验一................................................... 错误!未定义书签。

实验二................................................... 错误!未定义书签。

实验三................................................... 错误!未定义书签。

实验四................................................... 错误!未定义书签。

实验五................................................... 错误!未定义书签。

实验六................................................... 错误!未定义书签。

实验七................................................... 错误!未定义书签。

实验八................................................... 错误!未定义书签。

实验总结................................................. 错误!未定义书签。

在学习了MPI之后,我们又继续学习了有关openMP的并行运算,通过老师的细致讲解,我们对openMP有了一个初步的了解:OpenMP简介OpenMP是一种用于共享内存并行系统的多线程程序设计的库(Compiler Directive),特别适合于多核CPU上的并行程序开发设计。

它支持的语言包括:C 语言、C++、Fortran;不过,用以上这些语言进行程序开发时,并非需要特别关注的地方,因为现如今的大多数编译器已经支持了OpenMP,例如:Sun Compiler,GNU Compiler、Intel Compiler、Visual Studio等等。

程序员在编程时,只需要在特定的源代码片段的前面加入OpenMP专用的#pargma omp预编译指令,就可以“通知”编译器将该段程序自动进行并行化处理,并且在必要的时候加入线程同步及通信机制。

当编译器选择忽略#pargma omp预处理指令时,或者编译器不支持OpenMP时,程序又退化为一般的通用串行程序,此时,代码依然可以正常运作,只是不能利用多线程和多核CPU来加速程序的执行而已。

OpenMP使得程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。

对基于数据分集的多线程程序设计,它是一个很好的选择。

同时,使用OpenMP也提供了更强的灵活性,可以较容易的适应不同的并行系统配置。

线程粒度和负载平衡等是传统多线程程序设计中的难题,然而,在OpenMP中,OpenMP 库从程序员手中接管了部分这两方面的工作,从而使得程序员可以更加专注于具体的算法本身,而非如何编程使得代码在CPU负载平衡和线程粒度方面做出平衡。

但是,作为高层抽象,OpenMP并不适合需要复杂的线程间同步和互斥的场合。

OpenMP的另一个缺点是不能在非共享内存系统(如计算机集群)上使用。

在这样的系统上,MPI使用较多。

实验步骤:通过编写了一些程序,验证了关于openMP的一些简单的性质。

实验一代码:#include ""#include <cstdio>#include <cstdlib>int main(int argc, char *argv[]){int id, numb;omp_set_num_threads(3);#pragma omp parallel private(id, numb){id = omp_get_thread_num();numb = omp_get_num_threads();printf("I am thread %d out of %d \n", id, numb);}system("pause");return 0;}实验结果:可以看到,因为三个进程同步执行,所以输出顺序是乱序的,就是表示运行优先级相同。

当把进程数改成10的时候,得到下面的结果:与上面的到的结论(并行并行运算)相同。

实验二代码:#include ""#include <cstdio>#include <cstdlib>int main(int argc, char *argv[]){int id;omp_set_num_threads(2);#pragma omp parallel{printf("what will you see\n");#pragma omp forfor( int i = 1; i <= 5; ++i ){printf( " i = %d of %d\n", i,omp_get_thread_num() );printf("How many answers\n");}}system("pause");return 0;}实验运行结果:可以看到,在设置进程为2的情况之下,运算(计算规模)被等可能的分配给各个进程。

实验三代码:#include <iostream>#include <cstdlib>#include <>int main(){#pragma omp parallel sections实验四代码:#include<cstdlib>#include<iostream>#include<>int main(){#pragma omp parallel{for (int i = 0; i < 100; ++i){std::cout << i << "+" << std::endl;}#pragma omp barrierfor (int j = 0; j < 10; ++j){std::cout << j << "-" << std::endl;}}system("pause");return 0;}运行结果:结果分析:在语句 #pragma omp barrier 的作用下,只有当上面所有的进程计算工作全部完成之后,才会继续barrier之后的工作。

实验五代码:#include <cstdlib>#include <iostream>#include <cstdlib>#include <>using namespace std;int main(){int sum = 0;cout << "Before: " << sum << endl; #pragma omp parallel forfor(int i = 0; i < 100; i++){#pragma omp critical (a){sum += i;sum += i * 2;}}cout << "After: " << sum << endl;system("pause");return 0;}运行结果:结果分析:CRITICAL指令指定一块同一时间只能被一条线程执行的代码区域各个线程还是并行执行for里面的语句,但当你们执行到critical里面时,要注意有没有其他线程正在里面执行,如果有的话,要等其他线程执行完再进去执行。

实验六代码:#include<cstdlib>#include<iostream>#include<cstdlib>#include<>using namespace std;#define NUM_THREADS 2static long num_steps = 100000;int main(){int i, id;double x, pi, sum = ;double step = / (double) num_steps;omp_set_num_threads(NUM_THREADS);#pragma omp parallel private(x, i, id) reduction(+:sum) {id = omp_get_thread_num();for(i = id + 1; i <= num_steps; i = i + NUM_THREADS){x = (i - * step;sum += / + x * x);}}pi = sum * step;printf("pi = %.12f\n", pi);system("pause");return 0;}运行结果:结果分析:很简单,通过并行运算,发挥计算机多核的优势,自然能够较单核计算更快的得出计算结果,但是要注意计算机的核数是有限制的,不能无限扩大并行计算线程。

实验七代码:#include<cstdlib>#include<iostream>#include<cstdlib>#include<>using namespace std;int i = 0, sum1, sum2, sum3, sum;int main(){#pragma omp parallel sections num_threads(3) {#pragma omp sectionfor(i = 0; i < 100; i++)sum1 += i;#pragma omp sectionfor(i = 100; i < 200; i++)sum2 += i;#pragma omp sectionfor(i = 200; i < 300; i++)sum3 += i;}sum = sum1 + sum2 + sum3;printf("sum = %d\n", sum);system("pause");return 0;}运行结果:结果分析:这里需要将累计求和值得部分和分配给几个变量的原因是:当多个线程并行执行时,有可能多个线程同时对某变量进行了读写操作,从而导致不可预知的结果,因为多线程计算如果只设置一个sum,每次增加的值可能是不同进程的,从而导致运算结果混乱,但是如果把不同进程的计算结果分别保存,这样就不会出现结算结果错误的问题。

相关主题