私は削減を使ってCUDAでこの操作を実行する方法を考えていましたが、それを達成する方法について少し迷っています。 Cコードは以下の通りです。注意すべき重要な部分 - 変数precalculatedValueは、とループイテレータに依存します。また、変数ngoは、mのすべての値に固有のものではありません。 メートル = 4,5,6,7,8、私は場合に、ループイテレータのサイズが含まれている等NGO = 2を有することができる一方、メートル = 0,1,2は、NGO = 1を持っているかもしれませんより良い実装提案を提供するのに役立ちます。前場合ネストされたループ内の配列の2次元の累積合計 - CUDA実装?
// macro that translates 2D [i][j] array indices to 1D flattened array indices
#define idx(i,j,lda) ((j) + ((i)*(lda)))
int Nobs = 60480;
int NgS = 1859;
int NgO = 900;
// ngo goes from [1,900]
// rInd is an initialized (and filled earlier) as:
// rInd = new long int [Nobs];
for (m=0; m<Nobs; m++) {
ngo=rInd[m]-1;
for (n=0; n<NgS; n++) {
Aggregation[idx(n,ngo,NgO)] += precalculatedValue;
}
}
precalculatedValueは、内側ループ変数のみの関数であった場合、私はユニークな配列インデックスの値を保存し、事後に平行還元(推力)でそれらを添加しました。しかし、この場合、私は困惑しています。mの値は、ngoの値に一意にマップされません。したがって、私は、このコードを効率化する(または実行可能にする)方法を、削減を使用する方法は見ていません。どんなアイディアも大歓迎です。
+1:「シンプルな方法でパフォーマンスを測定し、最適化の方法を決めてください。 - 一般的なアドバイス、特にGPUのようなもの。 –
詳細な回答ありがとうございます!最初のステップとして、元のCアルゴリズムの出力は、転置されたループと同じであると判断しました。両方のイテレータに依存する様々な計算がありますが、出力の正確さに影響を与えずにこの簡単な変更を行うことができなかったことはわかりませんでした。私はここから進み、もしatomicAddが私に適切なパフォーマンスを与えるならば。 –
しかし私は1つの問題を忘れました。 precalculatedValue(a、b)型はdoubleです。 (実際には2つのdouble値を持つ構造体なので、操作は2回繰り返されます)これはパフォーマンス上のボトルネックになると思います。 –