c++ - 如何使用 g++ 编译 openmp

标签 c++ compilation 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<<"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 是一组 代码转换 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 线程)。

关于c++ - 如何使用 g++ 编译 openmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12002304/

相关文章:

c++ - boost 转换产生 Inf 返回值

c - 警告只有一个位域,而不是两个?

c++ - -Xlinker -export-dynamic 和 -rdynamic 之间有什么区别吗?

c# - 我可以 PInvoke C++ 可执行文件但不能共享库

c# - 从 C++ 调用 C# dll 时如何使用 app.config 文件

c++ - 如何获取打印机的DVTARGETDEVICE以使用ITextHost实现打印预览

c++ - 我的 c++filt 似乎不能正常工作,没有输出变化

perl - 检测编译后的perl脚本是否动态加载模块

c++ - 使用 OpenMP 线程和 std::(experimental::)simd 计算 Mandelbrot 集

c++ - 为什么类的大小取决于成员声明的顺序?如何?