OpenCL矩阵乘法就是一个例子

OpenCL矩阵乘法就是一个例子,opencl,matrix-multiplication,intel-fpga,Opencl,Matrix Multiplication,Intel Fpga,我对OpenCL非常陌生,正在浏览AlteraOpenCL示例。 在矩阵乘法示例中,他们使用了块的概念,其中输入矩阵的维数是块大小的倍数。代码如下: void matrixMult(//输入和输出矩阵 __全球浮动*C, __全球浮动*A, __全球浮动*B, //矩阵的宽度。 整数A_宽度,整数B_宽度) { //输入矩阵块a和B的本地存储 __本地浮点A_local[块大小][块大小]; __本地浮点B_local[块大小][块大小]; //块索引 int block_x=获取组id(0);

我对OpenCL非常陌生,正在浏览AlteraOpenCL示例。 在矩阵乘法示例中,他们使用了块的概念,其中输入矩阵的维数是块大小的倍数。代码如下:

void matrixMult(//输入和输出矩阵
__全球浮动*C,
__全球浮动*A,
__全球浮动*B,
//矩阵的宽度。
整数A_宽度,整数B_宽度)
{
//输入矩阵块a和B的本地存储
__本地浮点A_local[块大小][块大小];
__本地浮点B_local[块大小][块大小];
//块索引
int block_x=获取组id(0);
int block_y=get_group_id(1);
//本地ID索引(块内的偏移量)
int local_x=获取本地id(0);
int local_y=get_local_id(1);
//计算循环边界
int a_start=a_宽度*块大小*块y;
int a_end=a_start+a_width-1;
int b_start=块大小*块x;
浮动运行_和=0.0f;

for(int a=a_start,b=b_start;a
a_local
b_local
都由工作组的所有工作项共享,因此在包含
for
循环的每个步骤中,它们的所有元素都并行加载(由工作组的所有工作项加载)

然后,每个工作项使用一些加载的值(不一定是工作项本身加载的值)来完成其部分计算

最后,工作项将其单个结果存储到全局输出矩阵中


这是一个经典的矩阵乘法的平铺实现。然而,我真的很惊讶没有看到任何类型的内存同步函数调用,比如
work\u group\u barrier(CLK\u LOCAL\u MEM\u FENCE)
A_local
B_local
的负载之间,以及它们在
k
循环中的使用……但是我很可能忽略了这里的一些东西。

在您的代码示例中肯定缺少了一个障碍。您拥有的外部for循环只有在所有工作项都在执行指令时才会产生正确的结果以锁步方式,从而确保在for k循环之前填充本地内存

Altera和其他FPGA可能就是这种情况,但这对于CPU和GPU是不正确的

如果获得意外结果,或希望与其他类型的硬件兼容,则应添加屏障(CLK_LOCAL_MEM_FENCE);

float running_sum = 0.0f;
for (int a = a_start, b = b_start; a <= a_end; a += BLOCK_SIZE, b += (BLOCK_SIZE * B_width))
{
    A_local[local_y][local_x] = A[a + A_width * local_y + local_x];
    B_local[local_x][local_y] = B[b + B_width * local_y + local_x];

    barrier(CLK_LOCAL_MEM_FENCE);

    #pragma unroll
    for (int k = 0; k < BLOCK_SIZE; ++k)
    {
        running_sum += A_local[local_y][k] * B_local[local_x][k];
    }
}
float running\u sum=0.0f;
对于(int a=a_开始,b=b_开始;a