2012-05-30 71 views
4

我有一個C++程序,它創建一個對象,然後調用這個對象的兩個相互獨立的函數。所以它看起來像這樣:並行計算的C++ + openmp:如何在visual studio中設置?

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

我想這兩個計算並行運行,以節省計算時間。我已經看到這可以使用openmp完成,但無法弄清楚如何設置它。我發現的唯一例子是將相同的計算(例如「hello world!」)發送到不同的核心,輸出是「hello world!」的2倍。在這種情況下我該怎麼做?

我使用的是Windows XP與Visual Studio 2005

回答

3

你應該看看sections OpenMP的結構的。它的工作原理是這樣的:

#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

0

的這第一部分是讓OpenMP的啓動和Visual Studio 2005中,這是很老運行;它需要做一些工作,但是在this question的答案中有所描述。

一旦這樣做了,這是相當容易,如果你有兩個方法:這是真正獨立的完全做任務並行的這種簡單的形式。請注意,限定符;如果方法閱讀相同的數據,這是確定的,但如果他們要更新任何狀態,其他方法使用或調用任何其他例程這樣做,那麼事情將打破。

只要方法是完全獨立的,您可以使用sections這些(tasks實際上是更現代的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 
+0

即使最新最好的Visual Studio 11仍然只支持OpenMP 2.0。看起來MS正在竭盡全力將並行處理帶入.Net平臺。 –

+0

OOF;我不知道事情是那麼糟糕。 –

+0

您正在寫入來自兩個不同線程(並行)的相同變量(答案)。不要這樣做。 – Simon

1

如果這是需要你的代碼的內存不是很多,你可以使用MPI庫了。爲了這個目的,首先從本教程Compiling MPI Programs in Visual Studio 或從這裏開始你的視覺工作室安裝MPI:MS-MPI with Visual Studio 2008 使用這種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; 
} 

爲你的基礎代碼,添加功能並申報工作每個進程的例子如果有以下聲明:

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

function1和function2可以是你喜歡的任何東西,你可以同時執行;但要小心這兩個功能彼此獨立。 多數民衆贊成它!