如何使用g ++编译openmp [英] How to compile openmp using g++
问题描述
我有一个关于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
在使用超过三个OpenMP线程运行此代码时,您在GCC中遇到了一个错误,将在下一版本中修复)
g ++ test.o -o test -fopenmp -lpthread
$ c $
任何人都可以告诉我如何编译这个代码正确。谢谢。
解决方案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
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 librarylibgomp
- 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 yourmain
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屋!