如何使用 g++ 编译 openmp
Posted
技术标签:
【中文标题】如何使用 g++ 编译 openmp【英文标题】:How to compile openmp using g++ 【发布时间】:2012-08-17 08:25:24 【问题描述】: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<<"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;
首先,我使用以下代码编译它:
g++ test.cpp -fopenmp -lpthread
而且,我得到了正确的答案,总共有 3 个线程。
但是,当我这样编译时:
g++ -c test.cpp -o test.o
g++ test.o -o test -fopenmp -lpthread
只有一个线程。
任何人都可以告诉我如何正确编译这段代码。提前谢谢你。
【问题讨论】:
我认为 OpenMP 编译指示会被忽略,除非你有-fopenmp
。因此,在所有具有 OpenMP 编译指示的模块上都需要 -fopenmp
。
@Mysticial 你认为我应该在将 .cpp 编译为 .o 文件时添加 -fopenmp 吗?
是的。试试g++ -c test.cpp -o test.o -fopenmp
。如果可行,我会给出答案。
@Mysticial 那是工作。非常感谢。
【参考方案1】:
OpenMP 是一组 代码转换 pragma,即它们仅在编译时应用。您不能将代码转换应用于已编译的目标代码(好吧,您可以,但它涉及的过程要多得多,并且超出了当今大多数编译器所做的范围)。在链接阶段您需要-fopenmp
,仅用于编译器自动链接 OpenMP 运行时库libgomp
- 它对目标代码没有任何其他作用。
附带说明,虽然技术上是正确的,但您的代码以非常非 OpenMP 的方式执行 OpenMP。首先,您重新实现了 OpenMP sections
构造。 main
函数中的并行区域可以用更 OpenMP 的方式重写:
#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;
(如果您在使用超过三个 OpenMP 线程运行此代码时收到 SIGILL
,则您遇到了 GCC 中的错误,将在即将发布的版本中修复)
其次,您可能想看看 OpenMP task
构造。使用它,您可以将代码段排队,以由任何空闲线程作为任务同时执行。不幸的是,它需要一个支持 OpenMP 3.0 的编译器,这从等式中排除了 MSVC++,但前提是您关心 Windows 的可移植性(您显然不关心,因为您使用的是 POSIX 线程)。
【讨论】:
+1 表示超越实际更仔细地查看 OP 代码的职责。【参考方案2】:OpenMP 编译指示仅在使用 -fopenmp
编译时启用。否则编译器会完全忽略它们。 (因此,只有 1 个线程...)
因此,您需要将-fopenmp
添加到每个使用 OpenMP 的模块的编译中。 (而不仅仅是最后的链接步骤。)
g++ -c test.cpp -o test.o -fopenmp
g++ test.o -o test -fopenmp -lpthread
【讨论】:
以上是关于如何使用 g++ 编译 openmp的主要内容,如果未能解决你的问题,请参考以下文章
如何用openmp编译c ++? (在Windows 10中使用g ++)