我想知道以下代码片段的索引计数优先级(简单的二维矩阵乘法例程)。
kernel void mmul(
const int N,
global float* A,
global float* B,
global float* C)
{
int k;
int i = get_global_id(0);
int j = get_global_id(1);
float tmp;
if ((i < N) && (j < N))
{
tmp = 0.0f;
for (k = 0; k < N; k++)
tmp += A[i*N+k] * B[k*N+j];
C[i*N+j] = tmp;
}
}
如果您使用'k'计数器查看for循环内部,您可以看到全局工作项'i'和'j'放在同一行中。我想知道哪些在计算'i'和'j'的索引(例如1,2,3,4,...,n)方面具有优先权。我不明白这是如何工作的,因为我是OpenCl的新手,如果我只是使用普通的C或Python,我会使用嵌套的for循环来进行这种操作。
有人可以解释全球工作项的工作原理吗?
谢谢。
答案 0 :(得分:0)
您应该更多地关注内存读/写优先级而不是工作项发布顺序。要对内存操作强制执行优先级/顺序,请使用mem_fence(in-workitem),barrier(工作组)甚至内核(所有工作项同步点)。使用有意的空for循环或原子函数不能保证内存写/读优先级。只有内存栅栏/屏障/内核可以。
任何工作项(开始/结束运行)都没有优先级,但它们在具有许多线程的计算单元上进行分组和执行。无法保证工作项i,j将在i + 1,j + 1之前执行,但如果它们位于同一工作组(大小为16),则可以保证它们将在同一计算单元中执行(核心共享L1缓存) ,例如16)当使用Nvidia和Amd gpus时。
在同一计算单元中执行会增加同时发布的机会,这不是优先级,但共享资源如L1缓存意味着高性能。
即使在同一工作组中,也无法保证在其他工作项目之前是否发布了本地工作项目,但如果它们位于相同的SIMD单元上(例如Amd gpu中的16个部分),它们更可能同时发生