我正在尝试模拟类型的循环方程
s i (t+1) = f[Σ j W ij s j (t) + v i *input(t)]
在 OpenCL 中,其中 f(.) 是一些非线性函数(在下面的代码中,它只是一个具有阈值 th 的阶跃函数),而 s(t) 是一些外部输入。自然地,我为每个 x i实施了一个工人。在每个时间步中,每个工作人员都会计算上面等式的结果,然后将该结果与所有其他工作人员共享。因此,所有工人必须在同一个工作组中。
我当前的 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 实现慢了三倍。此外,我预计工作人员数量的变化不会产生太大的影响(因为新工作人员坐在与其他工作人员并行运行的新线程上),但实际上处理时间随着工作人员数量线性增加。瓶颈似乎是第一个障碍之后的写入操作。消除此操作(但保留屏障)将处理时间减少了 25 倍并消除了线性相关性。
我对 OpenCL 很陌生,如果能帮助我加快这段代码的速度,我将不胜感激!
提前非常感谢!Blue2script