Openmp编程练习

  • 2019 年 11 月 5 日
  • 筆記

火车卖票

// OpenMP2.cpp : 定义控制台应用程序的入口点。  //    #include "stdio.h"  #include "omp.h"  #include <windows.h>    //使用Sleep()函数需要包含此头文件    int num;  omp_lock_t lock;  int getnum()  {      int temp = num;      //omp_set_nest_lock(&lock);  #pragma omp atomic      num--;      //omp_unset_nest_lock(&lock);      return num+1;  }      void chushou(int i)  {        int s = getnum();      while (s >= 0)      {          omp_set_lock(&lock);          printf("站点%d卖掉了第%d张票n", i, s);          s = getnum();          omp_unset_lock(&lock);          Sleep(500);      }      }  int main()  {      num = 100;      int myid;      omp_init_lock(&lock);  #pragma omp parallel private(myid) num_threads(4)        {          myid = omp_get_thread_num();          //printf("my id is:%dn", myid);          chushou(myid);      }      omp_destroy_lock(&lock);        return 0;  }  

生产消费循环队列

  #include "stdio.h"  #include "omp.h"  #include <windows.h>    //使用Sleep()函数需要包含此头文件    int buf[5];//缓冲区的大小  int poi;  int poi2;  int num;  omp_lock_t lock;    void shengchan()  {      puts("shengchan");      while (true)      {          omp_set_lock(&lock);          if (num < 5)          {              while (buf[poi] == 1)poi = (poi + 1) % 5;              printf("生产者在%d位置上放置了一个n", poi);              buf[poi] = 1;              num++;              poi = (poi + 1) % 5;          }          omp_unset_lock(&lock);          Sleep(500);      }  }    void xiaofei()  {      puts("xiaofei");      while (true)      {          omp_set_lock(&lock);          //printf("%dn", num);          if (num>=1)          {                while (buf[poi2] == 0)poi2 = (poi2 + 1) % 5;                printf("消费者在%d位置上消费了一个n", poi2);              buf[poi2] = 0;              num--;            }          omp_unset_lock(&lock);          Sleep(500);      }  }  int main()  {      omp_init_lock(&lock);  #pragma omp parallel sections num_threads(2)      {  #pragma omp section          shengchan();  #pragma omp section          xiaofei();      }      omp_destroy_lock(&lock);      return 0;  }

蒙特卡洛圆周率

  #include "stdio.h"  #include "omp.h"  #include <windows.h>    //使用Sleep()函数需要包含此头文件  #include<time.h>  #include<iostream>    using namespace std;  double distance(double x, double y)  {      return sqrt((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5));  }    bool judge(double x,double y)  {      return distance(x, y) <= 0.5;  }  int in_num;    int main()  {      /*      for (int i = 1; i <= 5; i++)      {          cout << rand() / (double)RAND_MAX << endl;      }*/        bool flag = false;      double x;      double y;  #pragma omp for private(flag,x,y)      for (int i = 1; i <= 10000; i++)      {          x = rand() / (double)RAND_MAX;          y = rand() / (double)RAND_MAX;          flag = judge(x,y);          if (flag)          {  #pragma omp atomic              in_num++;          }          }      double ans = (double)in_num / 10000;      cout << ans*4 << endl;    }  

多线程二维数组和解法1 firstprivate+atomic

  #include "stdio.h"  #include "omp.h"  #include <windows.h>    //使用Sleep()函数需要包含此头文件  #include<time.h>  #include<iostream>    using namespace std;  int a[5][5] = { {1,1,1,1,1},{2,2,2,2,2},{3,3,3,3,3},{4,4,4,4,4},{5,5,5,5,5} };  int final_ans = 0;  void increase(int temp_sum)  {  #pragma omp atomic      final_ans += temp_sum;  }  int main()  {      int temp_sum=0;      int i,j;  #pragma omp parallel for private(i,j) firstprivate(temp_sum) num_threads(5)//每个线程必须一致,或者采用ppt上的例子进行划分      // firstprivate(temp_sum) reduction(+:temp_sum) 这两个不能同时出现      for (i = 0; i <= 4; i++)      {          //temp_sum += 1;          //printf("%d 当前的temp_sum值为%dn",i, temp_sum);          for (j = 0; j <= 4; j++)          {              temp_sum += a[i][j];          }          printf("temp_sum is %dn", temp_sum);          increase(temp_sum);          }      printf("%dn", final_ans);      return 0;  }

多线程二维数组解法2 线程可以不用对应数量

  #include "stdio.h"  #include "omp.h"  #include <windows.h>    //使用Sleep()函数需要包含此头文件  #include<time.h>  #include<iostream>    using namespace std;  int a[5][5] = { {1,1,1,1,1},{2,2,2,2,2},{3,3,3,3,3},{4,4,4,4,4},{5,5,5,5,5} };  int ans_buf[5];  int main()  {      int i, j;  #pragma omp parallel for num_threads(3) private(j)      for (int i = 0; i <= 4; i++)      {          for (int j = 0; j <= 4; j++)          {              ans_buf[i] += a[i][j];          }      }      int sum = 0;      for (int i = 0; i <= 4; i++)          sum += ans_buf[i];      printf("%dn", sum);  }