[解決済み] OpenMPにおける配列の削減
2022-02-12 09:37:31
質問
以下のプログラムを並列化しようとしているのですが、配列での削減の仕方がわかりません。無理なのは分かっているのですが、他に方法はないでしょうか?ありがとうございます。(間違ったmに対するreductionを追加してしまいましたが,やり方をアドバイスしていただきたいです)
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <omp.h>
using namespace std;
int main ()
{
int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
int S [10];
time_t start_time = time(NULL);
#pragma omp parallel for private(m) reduction(+:m)
for (int n=0 ; n<10 ; ++n ){
for (int m=0; m<=n; ++m){
S[n] += A[m];
}
}
time_t end_time = time(NULL);
cout << end_time-start_time;
return 0;
}
解決方法は?
OpenMPで配列の縮小を行うことは可能です。 Fortranでは、そのためのコンストラクトも用意されています。 C/C++では、自分でやる必要があります。 ここでは、その方法を2つ紹介します。
最初の方法は、プライベート版の
S
を各スレッドに適用し、並列に充填した後、それらを
S
をクリティカルセクションで表示します(以下のコードを参照してください)。 2番目の方法は、次元数10*nthreadsの配列を作成する。 この配列を並列に埋め、それを
S
クリティカルセクションを使用せずに 2番目の方法はもっと複雑で、特にマルチソケット・システムでは注意しないとキャッシュの問題が発生する可能性があります。 詳しくはこちらをご覧ください。
OpenMPでクリティカルセクションを使用せずにヒストグラムを埋める(配列の縮小)並列処理
最初の方法
int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
int S [10] = {0};
#pragma omp parallel
{
int S_private[10] = {0};
#pragma omp for
for (int n=0 ; n<10 ; ++n ) {
for (int m=0; m<=n; ++m){
S_private[n] += A[m];
}
}
#pragma omp critical
{
for(int n=0; n<10; ++n) {
S[n] += S_private[n];
}
}
}
第二の方法
int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
int S [10] = {0};
int *S_private;
#pragma omp parallel
{
const int nthreads = omp_get_num_threads();
const int ithread = omp_get_thread_num();
#pragma omp single
{
S_private = new int[10*nthreads];
for(int i=0; i<(10*nthreads); i++) S_private[i] = 0;
}
#pragma omp for
for (int n=0 ; n<10 ; ++n )
{
for (int m=0; m<=n; ++m){
S_private[ithread*10+n] += A[m];
}
}
#pragma omp for
for(int i=0; i<10; i++) {
for(int t=0; t<nthreads; t++) {
S[i] += S_private[10*t + i];
}
}
}
delete[] S_private;
関連
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】'cout'は型名ではない
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】Enterキーを押して続行する
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] 配列のベクトルを扱う正しい方法