Openmp编程练习

Posted tony100k

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Openmp编程练习相关的知识,希望对你有一定的参考价值。

火车卖票

// 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张票
", 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:%d
", 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位置上放置了一个
", 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("%d
", num);
        if (num>=1)
        {
            
            while (buf[poi2] == 0)poi2 = (poi2 + 1) % 5;
            
            printf("消费者在%d位置上消费了一个
", 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值为%d
",i, temp_sum);
        for (j = 0; j <= 4; j++)
        {
            temp_sum += a[i][j];
        }
        printf("temp_sum is %d
", temp_sum);
        increase(temp_sum);


    }
    printf("%d
", 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("%d
", sum);
}

以上是关于Openmp编程练习的主要内容,如果未能解决你的问题,请参考以下文章

openMP多线程编程

[openMP] OpenMP在visual studio和mac上的配置

OpenMP并行编程应用—加速OpenCV图像拼接算法

基于 MPI/OpenMP 混合编程的大规模多体(N-Body)问题仿真实验

OpenMP 并行编程

OpenMP 线程计数问题