4

我有一个 C++ 程序,它创建一个对象,然后调用该对象的 2 个相互独立的函数。所以它看起来像这样:

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

我想让这两个计算并行运行以节省计算时间。我已经看到这可以使用 openmp 完成,但无法弄清楚如何设置它。我发现的唯一示例是将相同的计算(例如“hello world!”)发送到不同的核心,输出是“hello world!”的 2 倍。在这种情况下我该怎么做?

我使用 Windows XP 和 Visual Studio 2005。

4

3 回答 3

3

您应该研究sectionsOpenMP 的构造。它是这样工作的:

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

鉴于团队中至少有两个线程,这两个块可能会并行执行,但由实现决定如何以及在何处执行每个部分。

有一个使用 OpenMP 任务的更简洁的解决方案,但它要求您的编译器支持 OpenMP 3.0。MSVC 仅支持 OpenMP 2.0(即使在 VS 11 中!)。

您应该在项目设置中明确启用 OpenMP 支持。如果您从命令行进行编译,选项是/openmp.

于 2012-05-30T13:56:03.643 回答
1

如果您的代码所需的内存不是很多,您也可以使用 MPI 库。为此,首先从本教程在 Visual Studio 中编译 MPI 程序 或从此处在您的 Visual Studio 上安装 MPI:MS-MPI with Visual Studio 2008 use this mpi hello world code:

#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;
}

对于您的基本代码,将您的函数添加到其中并使用此示例 if 语句声明每个进程的作业:

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

function1 和 function2 可以是任何你喜欢同时执行的东西;但请注意,这两个功能相互独立。而已!

于 2012-06-01T12:35:11.490 回答
0

第一部分是让 OpenMP 与 Visual Studio 2005 一起运行,它已经很老了。这需要做一些事情,但在这个问题的答案中有描述。

一旦完成,如果您有两种真正完全独立的方法,那么执行这种简单形式的任务并行就相当容易了。注意限定符;如果这些方法正在读取相同的数据,那没关系,但是如果它们正在更新另一个方法使用的任何状态,或者调用任何其他这样做的例程,那么事情就会中断。

只要方法完全独立,您就可以使用这些部分任务实际上是更现代的 OpenMP 3.0 执行此操作的方法,但您可能无法获得 OpenMP 3.0 对如此旧的编译器的支持);您还将看到人们滥用并行 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;
}

运行这个给出

$  ./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
于 2012-05-30T14:04:20.367 回答