C++ 如何使用 g++ 编译 openmp

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12002304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:44:55  来源:igfitidea点击:

How to compile openmp using g++

c++compilationg++openmp

提问by Gang.Wang

I have a problem about the openmp compiling.

我有关于 openmp 编译的问题。

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.

而且,我得到了正确的答案,总共有 3 个线程。

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.

任何人都可以告诉我如何正确编译这段代码。先感谢您。

回答by Hristo Iliev

OpenMP is a set of code transformingpragmas, 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 -fopenmpduring the link phase only for the compiler to automatically link the OpenMP runtime library libgomp- it does nothing else to the object code.

OpenMP 是一组代码转换编译指示,即它们仅在编译时应用。您不能将代码转换应用于已编译的目标代码(好吧,您可以,但它涉及的过程要多得多,并且超出了当今大多数编译器所做的范围)。您只需要-fopenmp在链接阶段编译器自动链接 OpenMP 运行时库libgomp- 它不会对目标代码执行任何其他操作。

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

附带说明一下,虽然在技术上是正确的,但您的代码以非常非 OpenMP 的方式执行 OpenMP。首先,您重新实现了 OpenMPsections构造。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;
        }
    }
}

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

(如果您SIGILL在使用超过三个 OpenMP 线程运行此代码时遇到了 GCC 中的错误,该错误将在即将发布的版本中修复)

Second, you might want to take a look at OpenMP taskconstruct. 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).

其次,您可能想看看 OpenMPtask构造。有了它,您可以将要由任何空闲线程作为任务并发执行的代码段排队。不幸的是,它需要一个支持 OpenMP 3.0 的编译器,这将 MSVC++ 排除在等式之外,但前提是您关心 Windows 的可移植性(显然您不关心,因为您使用的是 POSIX 线程)。

回答by Mysticial

The OpenMP pragmas are only enabled when compiled with -fopenmp. Otherwise they are completely ignored by the compiler. (Hence, only 1 thread...)

OpenMP 编译指示仅在使用-fopenmp. 否则它们会被编译器完全忽略。(因此,只有 1 个线程...)

Therefore, you will need to add -fopenmpto the compilation of every single module that uses OpenMP. (As opposed to just the final linking step.)

因此,您将需要添加-fopenmp到使用 OpenMP 的每个模块的编译中。(而不仅仅是最后的链接步骤。)

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