Matrix 优化矩阵乘法OpenCL-目的:学习如何管理内存
我是OpenCL新手,试图了解如何优化矩阵乘法以熟悉各种范式。这是当前的代码。 如果我将矩阵A和B相乘,我在私有内存中分配一行A(因为每个工作项都使用它),在本地内存中分配一列B(因为每个工作组都使用它) 1) 代码目前是不正确的,不幸的是,我正在努力学习如何使用本地工作ID来获得正确的代码,但是我找不到我的错误?我是基于自己,但(幻灯片27)这似乎是错误的,因为他们没有在内部循环中使用loc_大小) 2) 您是否建议对该代码进行其他优化Matrix 优化矩阵乘法OpenCL-目的:学习如何管理内存,matrix,opencl,gpu,Matrix,Opencl,Gpu,我是OpenCL新手,试图了解如何优化矩阵乘法以熟悉各种范式。这是当前的代码。 如果我将矩阵A和B相乘,我在私有内存中分配一行A(因为每个工作项都使用它),在本地内存中分配一列B(因为每个工作组都使用它) 1) 代码目前是不正确的,不幸的是,我正在努力学习如何使用本地工作ID来获得正确的代码,但是我找不到我的错误?我是基于自己,但(幻灯片27)这似乎是错误的,因为他们没有在内部循环中使用loc_大小) 2) 您是否建议对该代码进行其他优化 __kernel void mmul( __glo
__kernel void mmul(
__global int* C,
__global int* A,
__global int* B,
const int rA,
const int rB,
const int cC,
__local char* local_mem)
{
int k,ty;
int tx = get_global_id(0);
int loctx = get_local_id(0);
int loc_size = get_local_size(0);
int value = 0 ;
int tmp_array[1000];
for(k=0;k<rB;k++) {
tmp_array[k] = A[tx * cA + k] ;
}
for (ty=0 ; ty < cC ; ty++) { \n" \
for (k = loctx ; k < rB ; k+=loc_size) {
local_mem[k] = B[ty + k * cC] ;
}
barrier(CLK_LOCAL_MEM_FENCE);
value = 0 ;
for(k=0;k<rB;k+=1) {
int i = loctx + k*loc_size;
value += tmp_array[k] * local_mem[i];
}
C[ty + (tx * cC)] = value;
}
}
local_wi_size是结果行/计算单元数(这样结果行%compute units==0)您的代码非常接近,但对本地内存数组的索引实际上比您想象的简单。在私有内存中有一行,在本地内存中有一列,需要计算这两个向量的点积。您只需对
行[k]*col[k]
求和,对于k=0
到N-1
:
for(k=0;k<rB;k+=1) {
value += tmp_array[k] * local_mem[k];
}
您可以在屏幕上找到与幻灯片配套的全套练习和解决方案。同一教程中还提供了一套更完整的幻灯片,接下来展示了一个更优化的矩阵乘法示例,该示例使用块方法更好地利用时间和空间位置。前面提到的缺少屏障的错误已在示例解决方案代码中修复,但尚未在幻灯片上修复。您的代码示例是否得到正确的结果?你试过更小的矩阵吗?全球和本地工作维度是什么?
for(k=0;k<rB;k+=1) {
value += tmp_array[k] * local_mem[k];
}
__kernel void mmul(
__global int* C,
__global int* A,
__global int* B,
const int rA,
const int rB,
const int cC,
__local char* local_mem)
{
int k,ty;
int tx = get_global_id(0);
int loctx = get_local_id(0);
int loc_size = get_local_size(0);
int value = 0;
int tmp_array[1000];
for(k=0;k<rB;k++) {
tmp_array[k] = A[tx * cA + k] ;
}
for (ty=0 ; ty < cC ; ty++) {
for (k = loctx ; k < rB ; k+=loc_size) {
local_mem[k] = B[ty + k * cC];
}
barrier(CLK_LOCAL_MEM_FENCE); // First barrier to ensure writes have finished
value = 0;
for(k=0;k<rB;k+=1) {
value += tmp_array[k] * local_mem[k];
}
C[ty + (tx * cC)] = value;
barrier(CLK_LOCAL_MEM_FENCE); // Second barrier to ensure reads have finished
}
}