質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

Q&A

解決済

1回答

396閲覧

c++のプログラムの並列化を行いたい

mikocchan

総合スコア4

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

0グッド

0クリップ

投稿2022/10/01 07:34

編集2022/10/01 08:39

前提

C++でシミュレーションを実装しました.実装したシミュレーションは問題なく
動くのですが,計算にかかる時間がとても長いです.
また,includeしているヘッダファイルはクラスsimulation に関係するものなので,
今回の並列化には影響はないと考えております.

実現したいこと

並列化を行うことで,計算にかかる時間を短くしたいです.
具体的には,以下のコードのfor(int i=0;i<50;i++)の50個の処理を並列化したいです.
そのための並列化の方法を教えていただきたいです.

該当のソースコード

C++

1#include "customerRecord.h" 2#include "customerCollection.h" 3#include "simulation5.h" 4#include <fstream> 5#include <string> 6#include <time.h> 7int main(){ 8 time_t start_time, end_time; 9 const double MAX = 120000000; 10 pair<double,double> ans_simu;//first:AoIの値、second:信頼誤差の値 11 double mu1 = 1; 12 double mu2; 13 double first_cin = false;//ファイル書き込み用,一番初めの値が書き込まれたらtrueに 14 for(int i=0;i<50;i++){//【この50のfor文の並列化を行いたい】 15 start_time = time(NULL);//処理開始前時間 16 mu2 = ((double)i / 10) + 0.1;//0.1~5.0まで 17 18 int L2_0_kugiri = 100;//c=0~9.9まで0.1刻み 19 int L2_1_kugiri = 100; 20 int L2_2_kugiri = 100; 21 double k_0_border = 0;//実際に刻んだ閾値 22 double k_1_border = 0; 23 double k_2_border = 0; 24 double bestAoI = 0;//最適なAoIを格納 25 double bestgosa= 0;//最適なAoIをとった時の信頼誤差を格納 26 double best_k_0_border = 0;//最適なAoIをとったときの閾値を確保 27 double best_k_1_border = 0; 28 double best_k_2_border = 0; 29 30 bestAoI = MAX; 31 for(int k_0=0;k_0<L2_0_kugiri;k_0++){ 32 k_0_border = (double) k_0 / 10; 33 for(int k_1=0;k_1<L2_1_kugiri;k_1++){ 34 k_1_border = (double) k_1 / 10; 35 for(int k_2=0;k_2<L2_2_kugiri;k_2++){ 36 k_2_border = (double) k_2 / 10; 37 simulation simu(mu1,mu2,k_0_border,k_1_border,k_2_border); 38 ans_simu = simu.AoI_return(mu1,mu2,k_0_border,k_1_border,k_2_border);//first:平均AoI,second:信頼誤差 39 if(bestAoI > ans_simu.first){//より最適な平均AoIを発見した場合,その時のAoI,誤差,閾値を保存 40 bestAoI = ans_simu.first; 41 bestgosa = ans_simu.second; 42 best_k_0_border = k_0_border; 43 best_k_1_border = k_1_border; 44 best_k_2_border = k_2_border; 45 } 46 } 47 } 48 } 49 end_time = time(NULL);//プログラム実行時間計算用 50 cout << " コード実行時間" << end_time - start_time << "秒," << endl; 51 cout << "mu2 = " << mu2 << "fin" << endl; 52 53 54 //値の出力 55 if(first_cin == false){//一回めだけ,ファイルを新規作成 56 first_cin = true; 57 ofstream fout1; 58 string filename1 = "heiretumae.dat"; 59 fout1.open(filename1, std::ios::out); 60 fout1 << mu2 << " " << bestAoI << " " << bestgosa << " " << best_k_0_border << " " << best_k_1_border << " " << best_k_2_border << endl; 61 fout1.close(); 62 } 63 else{//最初以外は追記 64 ofstream fout1; 65 string filename1 = "heiretumae.dat"; 66 fout1.open(filename1, std::ios::app); 67 fout1 << mu2 << " " << bestAoI << " " << bestgosa << " " << best_k_0_border << " " << best_k_1_border << " " << best_k_2_border << endl; 68 fout1.close(); 69 } 70 } 71 return 0; 72}

試したこと

OpenMPについて調べましたが,共有変数のあたりでつまづいてしまいました.

補足情報(FW/ツールのバージョンなど)

C++11を使用しております.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2022/10/01 08:31

で、提示のコードではどういう問題があるんでしょうか。
mikocchan

2022/10/01 08:36

申し訳ございません.こちらのコードを並列化するためにどうすればいいかという質問でした.
episteme

2022/10/02 03:56

たとえば i = 0~9, 10~19, 20~29、30~39, 40~49 の5つの範囲に分割し、 それぞれの計算ををスレッドに割り当てれば5スレッドで計算できます。
mikocchan

2022/10/05 09:48

そのスレッドの分け方を詳しく教えていただきたいです,, 質問がわかりづらくて申し訳ございません,,,
episteme

2022/10/05 09:50

詳しく、と言われましても...std::thread の使い方からですか? それはご勘弁。
guest

回答1

0

ベストアンサー

スレッドの並列化は難しいと思うので,プログラムを少し変更してプロセス側で並列化してはどうでしょうか?

main関数を中を次のような形で変更します。

c++

1#include <sstream> 2 3 4int main(int argc, char* argv[]) { 5 if (argc <= 2) { 6 std::cerr << "./simulation start end" << std::endl; 7 return 1; 8 } 9 int n_start; 10 int n_end; 11 std::istringstream(argc[1]) >> n_start; 12 std::istringstream(argc[2]) >> n_end; 13 14.... 15 16 for (int i=n_loop_start;i<n_loop_end;i++){// 17 18.... 19 20 string filename1 = "heiretu_" + std::to_string(n_start) 21 + "-" + std::to_string(n_end) + ".dat"; 22

として,実行側でオプションをつけて並列実行すればOKだと思います。
linuxのbashだと後ろに&をつけるだけでいいかと。

bash

1./simulation 0 10 & 2./simulation 10 20 & 3./simulation 20 30 & 4./simulation 30 40 & 5./simulation 40 50 &

windowsだとバッチファイルからstart コマンドで実行すればよいでしょうか。

投稿2022/11/12 10:32

ujimushi_sradjp

総合スコア2101

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問