OpenCL

时间:2018-03-02 18:14:00

标签: performance opencl gpu matrix-multiplication

很抱歉,如果我问一个非常简单的问题,但我在网上找不到任何相关的答案。

我正在尝试使用OpenCL在GPU上执行两次矩阵乘法,R = A B C。他们这样做,是通过对A和B执行矩阵乘法,然后将中间结果(I)存储在GPU DRAM上,然后在I和C之间进行另一个矩阵乘法。我当前的内核也可以处理批量矩阵。

以下是我的MatMul内核的代码(它只是一个基本版本,没有优化):

__kernel void MatrixMultiplication2 (const __global float* A,
                                     const __global float* B,
                                     __global float* C,
                                     const int A_height, const int A_width,
                                     const int B_height, const int B_width,
                                     const int C_height, const int C_width) {

        const int row = get_global_id (0);
        const int col = get_global_id (1);
        const int imgID = get_global_id (2);

        const int offsetA = A_height * A_width * imgID;
        const int offsetB = B_height * B_width * imgID;
        const int offsetC = C_height * C_width * imgID;

        float acc = 0.0f;

        for (int k = 0; k < A_width; k++) {
                acc += A[row*A_width + k + offsetA] * B[k*B_width + col + offsetB];
        }

        C[row*C_width + col + offsetC] = acc;


}

以下是我的主机代码中用于部署矩阵乘法的相关部分:

const size_t GWS1[3] = {A_height, B_width, batch_size};
const size_t LWS1[3] = {32, 32, 1};


const size_t GWS2[3] = {A_height, C_width, batch_size};
const size_t LWS2[3] = {32, 32, 1};

Event evKernel1 ("Kernel1");
Event evKernel2 ("Kernel2");

clFinish (queue);

high_resolution_clock::time_point t1 = high_resolution_clock::now();
err = clEnqueueNDRangeKernel (queue,
                              kernel1,
                              3,
                              NULL,
                              GWS1,
                              LWS1,
                              0,
                              NULL,
                              &evKernel1.CLEvent());

clFinish (queue);
CL_CHECK_ERROR (err);
err = clFinish (queue);
CL_CHECK_ERROR (err);
err = clWaitForEvents (1, &evKernel1.CLEvent());
CL_CHECK_ERROR (err);
evKernel1.FillTimingInfo ();

err = clEnqueueNDRangeKernel (queue,
                              kernel2,
                              3,
                              NULL,
                              GWS2,
                              LWS2,
                              0,
                              NULL,
                              &evKernel2.CLEvent());

clFinish (queue);
CL_CHECK_ERROR (err);
err =clFinish (queue);
CL_CHECK_ERROR (err);
err = clWaitForEvents (1, &evKernel2.CLEvent());
CL_CHECK_ERROR (err);

high_resolution_clock::time_point t2 = high_resolution_clock::now();

evKernel2.FillTimingInfo ();

readbackMemObject (queue, &mem_R, (int) sizeof (T), RSize, hostMem_R);

在GPU上进行多阶段矩阵乘法是否正确?我正在部署第一阶段,然后等到它完成然后部署第二阶段。在这种情况下,性能非常低,当我增加批量大小时,它会减少更多。我只是想知道这是否是顺序矩阵乘法的正常方法。

谢谢,

0 个答案:

没有答案