很抱歉,如果我问一个非常简单的问题,但我在网上找不到任何相关的答案。
我正在尝试使用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上进行多阶段矩阵乘法是否正确?我正在部署第一阶段,然后等到它完成然后部署第二阶段。在这种情况下,性能非常低,当我增加批量大小时,它会减少更多。我只是想知道这是否是顺序矩阵乘法的正常方法。
谢谢,