gpt4 book ai didi

c - OpenCL 转置内核如何使用 get_local_id

转载 作者:太空宇宙 更新时间:2023-11-04 02:59:57 24 4
gpt4 key购买 nike

取自示例的代码。我用它创建了一个项目并且它可以工作,但我不明白某些部分。

举个例子,假设我有一个 32x32 矩阵,有 36 个工作项,所以 get_global_id(0) 从 0 -> 35 我假设,并且 size = MATRIX_DIM/4 = 8。

__kernel void transpose(__global float4 *g_mat,
__local float4 *l_mat, uint size) {

__global float4 *src, *dst;

/* Determine row and column location */
int col = get_global_id(0);
int row = 0;
while(col >= size) {
col -= size--;
row++;
}
col += row;
size += row;

/* Read source block into local memory */
src = g_mat + row * size * 4 + col;
l_mat += get_local_id(0)*8;

clEnqueueNDRangeKernel 调用中,arg local_work_size 被设置为 NULL,根据手册,这意味着让编译器或其他东西解决:

local_work_size 也可以是 NULL 值,在这种情况下,OpenCL 实现将确定如何将全局工作项分解为适当的工作组实例。

但我不明白乘以 8,它给出了我想是工作组的本地内存中的地址偏移量。有人可以解释一下吗?

   l_mat[0] = src[0];
l_mat[1] = src[size];
l_mat[2] = src[2*size];
l_mat[3] = src[3*size];

/* Process block on diagonal */
if(row == col) {
src[0] =
(float4)(l_mat[0].x, l_mat[1].x, l_mat[2].x, l_mat[3].x);
src[size] =
(float4)(l_mat[0].y, l_mat[1].y, l_mat[2].y, l_mat[3].y);
src[2*size] =
(float4)(l_mat[0].z, l_mat[1].z, l_mat[2].z, l_mat[3].z);
src[3*size] =
(float4)(l_mat[0].w, l_mat[1].w, l_mat[2].w, l_mat[3].w);
}
/* Process block off diagonal */
else {
/* Read destination block into local memory */
dst = g_mat + col * size * 4 + row;
l_mat[4] = dst[0];
l_mat[5] = dst[size];
l_mat[6] = dst[2*size];
l_mat[7] = dst[3*size];

/* Set elements of destination block */
dst[0] =
(float4)(l_mat[0].x, l_mat[1].x, l_mat[2].x, l_mat[3].x);
dst[size] =
(float4)(l_mat[0].y, l_mat[1].y, l_mat[2].y, l_mat[3].y);
dst[2*size] =
(float4)(l_mat[0].z, l_mat[1].z, l_mat[2].z, l_mat[3].z);
dst[3*size] =
(float4)(l_mat[0].w, l_mat[1].w, l_mat[2].w, l_mat[3].w);

/* Set elements of source block */
src[0] =
(float4)(l_mat[4].x, l_mat[5].x, l_mat[6].x, l_mat[7].x);
src[size] =
(float4)(l_mat[4].y, l_mat[5].y, l_mat[6].y, l_mat[7].y);
src[2*size] =
(float4)(l_mat[4].z, l_mat[5].z, l_mat[6].z, l_mat[7].z);
src[3*size] =
(float4)(l_mat[4].w, l_mat[5].w, l_mat[6].w, l_mat[7].w);
}
}

最佳答案

l_mat 被用作工作组中线程的本地存储。具体来说,它被使用是因为对本地内存的访问比对全局内存的访问快几个数量级。

每个线程需要 8 个 float4。进行以下指针运算

l_mat += get_local_id(0)*8;

为每个线程移动 l_mat 指针,使其不与其他线程的数据重叠。

可能会导致错误,因为未指定 local_size,而且我们无法确保 l_mat 的大小足以存储每个线程的值。

关于c - OpenCL 转置内核如何使用 get_local_id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13262646/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com