如何使用g ++编译openmp [英] How to compile openmp using g++

查看:1090
本文介绍了如何使用g ++编译openmp的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于openmp编译的问题。



像下面的代码:

  #include< iostream> 
#include< pthread.h>
#include< omp.h>
#include< semaphore.h>
#include< stack>
using namespace std;
sem_t empty,full;
stack< int> stk;
void produce(int i)
{
{
sem_wait(& empty);
cout<<produce<< i * i<< endl;
stk.push(i * i);
sem_post(& full);
}
}
void consume1(int& x)
{
sem_wait(& full);
int data = stk.top();
stk.pop();
x = data;
sem_post(& empty);
}
void consume2()
{
sem_wait(& full);
int data = stk.top();
stk.pop();
cout<<consume2<<< data<< endl;
sem_post(& empty);
}
int main()
{
sem_init(& empty,0,1);
sem_init(& full,0,0);
pthread_t t1,t2,t3;
omp_set_num_threads(3);
int TID = 0;
#pragma omp parallel private(TID)
{
TID = omp_get_thread_num();
if(TID == 0)
{
cout<<有<< omp_get_num_threads()<<threads<< endl;
for(int i = 0; i <5; i ++)
产生(i);
}
else if(TID == 1)
{
int x;
while(true)
{
consume1(x);
cout<<consume1<<< x<< endl;
}
}
else if(TID == 2)
{
int x;
while(true)
{
consume1(x);
cout<<consume2<<< x<< endl;
}
}
}
返回0;
}

首先,使用以下代码编译它:

  g ++ test.cpp -fopenmp -lpthread 



但是,当我这样编译:

  g ++ -c test.cpp -o test.o 
g ++ test.o -o test -fopenmp -lpthread


任何人都可以告诉我如何编译这个代码正确。谢谢。

解决方案

OpenMP是一组代码转换在编译时。你不能将代码转换应用到已编译的目标代码(确定,你可以,但它是更多的涉及过程和超出了大多数编译器这些天的范围)。在链接阶段只需要 -fopenmp ,以便编译器自动链接OpenMP运行时库 libgomp - 它不执行任何操作



在一个侧面的注释,虽然技术上正确,你的代码执行OpenMP非常非OpenMP的方式。首先,您重新实现了OpenMP 构造。您的 main 函数中的并行区域可以以更多OpenMP方式重写:

  #pragma omp parallel sections 
{
#pragma omp section
{
cout<<有<< omp_get_num_threads()<线程<<< endl;
for(int i = 0; i <5; i ++)
产生(i);
}
#pragma omp section
{
int x;
while(true)
{
consume1(x);
cout<<consume1<<< x<< endl;
}
}
#pragma omp section
{
int x;
while(true)
{
consume1(x);
cout<<consume2<<< x<< endl;
}
}
}

c $ c> SIGILL 在使用超过三个OpenMP线程运行此代码时,您在GCC中遇到了一个错误,将在下一版本中修复)



其次,你可能想看看OpenMP task 构造。有了它,你可以排队的代码片段作为任务由任何空闲线程并发执行。不幸的是,它需要一个支持OpenMP 3.0的编译器,它从方程中排除MSVC ++,但只有当你关心对Windows的可移植性(你显然不,因为你使用POSIX线程)。


I have a problem about the openmp compiling.

Like the following code:

#include <iostream> 
#include <pthread.h>
#include <omp.h>
#include <semaphore.h>
#include <stack>
using namespace std;
sem_t empty,full;
stack<int> stk;
void produce(int i)
{
    {
    sem_wait(&empty);
            cout<<"produce "<<i*i<<endl;
            stk.push(i*i);
    sem_post(&full);
    }
}
void consume1(int &x)
{
    sem_wait(&full);
            int data=stk.top();
            stk.pop();
            x=data;
    sem_post(&empty);
}
void consume2()
{
    sem_wait(&full);
            int data=stk.top();
            stk.pop();
            cout<<"consume2 "<<data<<endl;
    sem_post(&empty);
}
int main()
{
    sem_init(&empty,0,1);
    sem_init(&full,0,0);
    pthread_t t1,t2,t3;
    omp_set_num_threads(3);
    int TID=0;
    #pragma omp parallel private(TID)
    {
            TID=omp_get_thread_num();
            if(TID==0)
            {
            cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl;
            for(int i=0;i<5;i++)
                    produce(i);
            }
            else if(TID==1)
            {
                    int x;
                    while(true)
                    {
                            consume1(x);
                            cout<<"consume1 "<<x<<endl;
                    }
            }
            else if(TID==2)
            {
                    int x;
                    while(true)
                    {
                            consume1(x);
                            cout<<"consume2 "<<x<<endl;
                    }
            }
    }
    return 0;
}

Firstly, I compile it using:

g++ test.cpp -fopenmp -lpthread

And, I got the right answer, there are 3 threads totally.

But, when I do the compile like this:

g++ -c test.cpp -o test.o
g++ test.o -o test -fopenmp -lpthread

there is just only ONE thread.

Anyone can tell me how to compile this code correctly. Thankyou in advance.

解决方案

OpenMP is a set of code transforming pragmas, i.e. they are only applied at compile time. You cannot apply code transformation to an already compiled object code (ok, you can, but it is far more involving process and outside the scope of what most compilers do these days). You need -fopenmp during the link phase only for the compiler to automatically link the OpenMP runtime library libgomp - it does nothing else to the object code.

On a side note, although techically correct, your code does OpenMP in a very non-OpenMP way. First, you have reimplemented the OpenMP sections construct. The parallel region in your main function could be rewritten in a more OpenMP way:

#pragma omp parallel sections
{
    #pragma omp section
    {
        cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl;
        for(int i=0;i<5;i++)
            produce(i);
    }
    #pragma omp section
    {
        int x;
        while(true)
        {
            consume1(x);
            cout<<"consume1 "<<x<<endl;
        }
    }
    #pragma omp section
    {
        int x;
        while(true)
        {
            consume1(x);
            cout<<"consume2 "<<x<<endl;
        }
    }
}

(if you get SIGILL while running this code with more than three OpenMP threads, you have encountered a bug in GCC, that will be fixed in the upcoming release)

Second, you might want to take a look at OpenMP task construct. With it you can queue pieces of code to be executed concurrently as tasks by any idle thread. Unfortunately it requires a compiler which supports OpenMP 3.0, which rules out MSVC++ from the equation, but only if you care about portability to Windows (and you obviously don't, because you are using POSIX threads).

这篇关于如何使用g ++编译openmp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆