簡體   English   中英

用於並行計算的C ++ + openmp:如何在visual studio中進行設置?

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

我有一個c ++程序,它創建一個對象,然后調用這個對象的2個函數,它們彼此獨立。 所以它看起來像這樣:

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

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

我在Visual Studio 2005中使用Windows XP。

您應該查看OpenMP的sections構造。 它的工作原理如下:

#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

如果您的代碼所需的內存不是很多,您也可以使用MPI庫。 為此,首先從本教程在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;
}

對於您的基本代碼,添加您的函數並使用此示例if語句聲明每個進程的作業:

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

function1和function2可以是你喜歡同時執行的任何東西; 但請注意這兩個功能彼此獨立。 而已!

第一部分是使用Visual Studio 2005啟動和運行OpenMP,這是相當陳舊的; 它需要一些工作,但它在這個問題的答案中描述。

完成后,如果您有兩種真正完全獨立的方法,那么執行這種簡單形式的任務並行化相當容易。 注意限定符; 如果方法正在讀取相同的數據,那沒關系,但是如果他們正在更新另一個方法使用的任何狀態,或者調用任何其他例程,那么事情就會破裂。

只要這些方法是完全獨立的,你可以使用這些部分任務實際上是更現代的,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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM