简体   繁体   English

用于并行计算的C ++ + openmp:如何在visual studio中进行设置?

[英]C++ + openmp for parallel computing: how to set up in visual studio?

I have a c++ program that creates an object and then calls 2 functions of this object that are independent from one another. 我有一个c ++程序,它创建一个对象,然后调用这个对象的2个函数,它们彼此独立。 So it looks like this: 所以它看起来像这样:

Object myobject(arg1, arg2);
double answer1 = myobject.function1();
double answer2 = myobject.function2();

I would like to have those 2 computations run in parallel to save computation time. 我希望这两个计算并行运行以节省计算时间。 I've seen that this could be done using openmp, but couldn't figure out how to set it up. 我已经看到这可以使用openmp完成,但无法弄清楚如何设置它。 The only examples I found were sending the same calculation (ie "hello world!" for example) to the different cores and the output was 2 times "hello world!". 我发现的唯一例子是向不同的核心发送相同的计算(例如“hello world!”),输出是“hello world!”的2倍。 How can I do it in this situation? 在这种情况下我该怎么做?

I use Windows XP with Visual Studio 2005. 我在Visual Studio 2005中使用Windows XP。

You should look into the sections construct of OpenMP. 您应该查看OpenMP的sections构造。 It works like this: 它的工作原理如下:

#pragma omp parallel sections
{
   #pragma omp section
   {
      ... section 1 block ...
   }
   #pragma omp section
   {
      ... section 2 block ...
   }
}

Both blocks might execute in parallel given that there are at least two threads in the team but it is up to the implementation to decide how and where to execute each section. 两个块可能并行执行,因为团队中至少有两个线程,但由实现来决定执行每个部分的方式和位置。

There is a cleaner solution using OpenMP tasks, but it requires that your compiler supports OpenMP 3.0. 使用OpenMP任务有一个更清晰的解决方案,但它要求您的编译器支持OpenMP 3.0。 MSVC only supports OpenMP 2.0 (even in VS 11!). MSVC仅支持OpenMP 2.0(即使在VS 11中也是如此)。

You should explicitly enable OpenMP support in your project's settings. 您应该在项目的设置中明确启用OpenMP支持。 If you are doing compilation from the command line, the option is /openmp . 如果从命令行进行编译,则选项为/openmp

If the memory that is is required for your code is not a lot you can use MPI library too. 如果您的代码所需的内存不是很多,您也可以使用MPI库。 For this purpose first of all install MPI on your visual studio from this tutorial Compiling MPI Programs in Visual Studio or from here: MS-MPI with Visual Studio 2008 use this mpi hello world code : 为此,首先从本教程在Visual Studio中编译MPI程序或从此处在Visual Studio上安装MPI: 使用Visual Studio 2008的MS-MPI使用此mpi hello world代码:

#include<iostream>
#include<mpi.h>
using namespace std;

int main(int argc, char** argv){

int mynode, totalnodes;

MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD, &mynode);

cout << "Hello world from process " << mynode;
cout << " of " << totalnodes << endl;

MPI_Finalize();
return 0;
}

for your base code, add your functions to it and declare job of each process with this example if statement: 对于您的基本代码,添加您的函数并使用此示例if语句声明每个进程的作业:

if(mynode== 0 ){function1}
if(mynode== 1 ){function2}

function1 and function2 can be any thing that you like executes at the same time; function1和function2可以是你喜欢同时执行的任何东西; but be careful that these two functions independent of each others. 但请注意这两个功能彼此独立。 thats it! 而已!

The first part of this is getting OpenMP up and running with Visual Studio 2005, which is quite old; 第一部分是使用Visual Studio 2005启动和运行OpenMP,这是相当陈旧的; it takes some doing, but it's described in the answer to this question . 它需要一些工作,但它在这个问题的答案中描述。

Once that's done, it's fairly easy to do this simple form of task parallelism if you have two methods which are genuinely completely independant. 完成后,如果您有两种真正完全独立的方法,那么执行这种简单形式的任务并行化相当容易。 Note that qualifier; 注意限定符; if the methods are reading the same data, that's ok, but if they're updating any state that the other method uses, or calling any other routines that do so, then things will break. 如果方法正在读取相同的数据,那没关系,但是如果他们正在更新另一个方法使用的任何状态,或者调用任何其他例程,那么事情就会破裂。

As long as the methods are completly independant, you can use sections for these ( tasks are actually the more modern, OpenMP 3.0 way of doing this, but you probably won't be able to get OpenMP 3.0 support for such an old compiler); 只要这些方法是完全独立的,你可以使用这些部分任务实际上是更现代的,OpenMP 3.0这样做的方式,但你可能无法获得OpenMP 3.0支持这样一个旧的编译器); you will also see people misusing parallel for loops to achieve this, which at least has the advantage of letting you control the thread assignments, so I include that here for completeness even though I can't really recommend it: 你也会看到人们滥用并行for循环来实现这一点,这至少具有让你控制线程分配的优势,所以我在这里包含了完整性,即使我不能真正推荐它:

#include <omp.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int f1() {
    int tid = omp_get_thread_num();
    printf("Thread %d in function f1.\n", tid);
    sleep(rand()%10); 
    return 1;
}

int f2() {
    int tid = omp_get_thread_num();
    printf("Thread %d in function f2.\n", tid);
    sleep(rand()%10); 
    return 2;
}


int main (int argc, char **argv) {

    int answer;
    int ans1, ans2;

    /* using sections */
#pragma omp parallel num_threads(2) shared(ans1, ans2, answer) default(none)
    {
#pragma omp sections 
        {
#pragma omp section
            ans1 =  f1();

#pragma omp section
            ans2 =  f2();
        }  

#pragma omp single
        answer = ans1+ans2;

    }  

    printf("Answer = %d\n", answer);

    /* hacky appraoch, mis-using for loop */
    answer = 0;
#pragma omp parallel for schedule(static,1) num_threads(2) reduction(+:answer) default(none)
    for (int i=0; i<2; i++)  {    
        if (i==0)
            answer += f1();
        if (i==1)
            answer += f2();
    }

    printf("Answer = %d\n", answer);

    return 0;
}

Running this gives 运行这个给出

$  ./sections 
Thread 0 in function f1.
Thread 1 in function f2.
Answer = 3
Thread 0 in function f1.
Thread 1 in function f2.
Answer = 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM