4

オブジェクトを作成し、このオブジェクトの互いに独立した 2 つの関数を呼び出す C++ プログラムがあります。したがって、次のようになります。

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

計算時間を節約するために、これら 2 つの計算を並行して実行したいと考えています。これは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 ...
   }
}

チームに少なくとも 2 つのスレッドがある場合、両方のブロックが並行して実行される可能性がありますが、各セクションを実行する方法と場所を決定するのは実装次第です。

OpenMP タスクを使用したよりクリーンなソリューションがありますが、それにはコンパイラが OpenMP 3.0 をサポートしている必要があります。MSVC は OpenMP 2.0 のみをサポートします (VS 11 でも!)。

プロジェクトの設定で OpenMP サポートを明示的に有効にする必要があります。コマンドラインからコンパイルを行う場合、オプションは/openmp.

于 2012-05-30T13:56:03.643 に答える
1

コードに必要なメモリが多くない場合は、MPI ライブラリも使用できます。この目的のために、まず、このチュートリアルVisual Studio での MPI プログラムのコンパイル から MPI を Visual Studioインストールし ます 。

#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 は、同時に実行する任意のものにすることができます。ただし、これら 2 つの機能が互いに独立していることに注意してください。それでおしまい!

于 2012-06-01T12:35:11.490 に答える
0

この最初の部分は、かなり古いVisualStudio2005でOpenMPを起動して実行することです。多少の作業が必要ですが、この質問への回答に記載されています。

それが完了すると、完全に独立した2つのメソッドがある場合、この単純な形式のタスク並列処理を実行するのはかなり簡単です。修飾子に注意してください。メソッドが同じデータを読み取っている場合は問題ありませんが、他のメソッドが使用する状態を更新している場合、または他のルーチンを呼び出している場合は、問題が発生します。

メソッドが完全に独立している限り、これらのセクションを使用できます(タスクは、実際にはこれを行うためのより最新の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 に答える