私は生物物理学の大学院生で、PyCUDA と Scipy を使用してタンパク質凝集モデルをプログラムしようとしていODEInt
ます。過去 2 週間以内に、コードを実行できるようになりましたが、非常に遅いです。私のコードが何をするのか説明できるかどうか見てみましょう。
各要素が長さのポリマーの濃度である濃度のnp
配列があります。各カーネルが特定の長さのポリマーの変化率を計算する場所を使用して、ポリマー濃度の変化率を計算する関数があります。この計算中に、長さの配列をスレッドで合計する必要があるため、コードが大幅に遅くなります。N
i+1
CUDA
(N-i-1)
少し読んでグーグルで調べてみると、並列処理を呼び出して配列の合計などのシリアル計算をはるかに高速化する方法として、並列削減に出くわしました。もちろん、私はマーク・ハリスのパワーポイントのスライドを参照しています. これらは素晴らしい読み物であり、これは私のコードを劇的に高速化する潜在的な方法のように見えますが、いくつか質問があります:
ポリマー種の数 N が ~ 8700 ~ 9000 である必要がある場合、CUDA を使用してこれらの N 配列を同時に削減することは考えられますか? 簡単な計算を行うと (同時スレッドの最大数を計算する方法に関する SO の優れた説明のおかげで可能になりました)、GTX Titan で一度に 15 * 64 * 32 = 30720 のスレッドを実行できることがわかりました。一度に最大 8960 個のカーネルでカーネルを呼び出すと、使用できるスレッドは 21760 個しか残っていないはずですよね? それを適切に削減するには、少なくとも (配列の長さ/2) スレッドが必要なように思われるので、私は絶望的です。
残りのスレッドを分割して、一度にいくつかの大きな配列をシリアルに削減することで、残りのスレッドを使用できるのではないかと考えていました。
わかりません...私はただの物理学の大学院生です。間違った方向への長い旅に出る前に、専門家に聞いてみようと思いました. カーネルに何かを減らすように簡単かつ効率的に伝えることは可能ですか?
ありがとう、カルステン
これが私がやろうとしていることの表現です。
fluxes and concs are np.arrays
dcdt(concs, t)
Call CUDA to calculate fluxes
Thread
0 fluxes[i] = stuff + sum(concs[n] for n from 1 to 9000)
1 fluxes[i] = stuff + sum(concs[n] for n from 2 to 9000)
2 fluxes[i] = stuff + sum(concs[n] for n from 3 to 9000)
...
N fluxes[i] = stuff
これまで説明してきた配列の合計は、基本的に各スレッドの同じ配列のより小さいバージョンであることに気付くでしょう。これは、これがホスト上で行うべきことなのかどうか疑問に思います。