タイプの再帰方程式をシミュレートしようとしています
s i (t+1) = f[Σ j W ij s j (t) + v i *input(t)]
ここで、f(.) は何らかの非線形関数 (以下のコードでは、しきい値 th を持つ単なるステップ関数です) であり、s(t) は何らかの外部入力です。当然、x iごとに 1 つのワーカーを実装しました。すべての時間ステップで、すべてのワーカーが上記の方程式の結果を計算し、その後、この結果が他のすべてのワーカーと共有されます。したがって、すべてのワーカーは同じワークグループに属している必要があります。
現在の OpenCL カーネルは次のようになります
__kernel void part1(__global int* s, __global float* W, __global float* Th, __global float* V, __global float* input, int N, int T)
{
unsigned int i = get_global_id(0);
float value = 0;
float v = V[i];
float th = Th[i];
for(int t = 0; t < T; t++){
value = v*input[t];
for(int j = 0; j < N; j++){
value = value + W[i*N + j]*s[j];
}
barrier(CLK_GLOBAL_MEM_FENCE);
if (value >= th){
s[i] = 1;
} else {
s[i] = 0;
}
barrier(CLK_GLOBAL_MEM_FENCE);
}
}
残念ながら、このコードは実際には同等の C 実装よりも 3 倍遅くなります。また、ワーカーの数を変更しても大きな違いは生じないと予想していましたが (新しいワーカーは、他のワーカーと並行して実行される新しいスレッドに座っているため)、実際には処理時間はワーカーの数に比例して増加します。ボトルネックは、最初の障壁の後の書き込み操作のようです。この操作をなくすと (ただし、バリアはそのままにしておくと)、処理時間が 25 分の 1 に短縮され、線形依存がなくなります。
私は OpenCL にかなり慣れていないので、このコードを高速化するための助けをいただければ幸いです!
よろしくお願いします!Blue2script