我使用OpenCL在Adreno GPU上实现GEMM。一般的想法是将结果矩阵C分成矩形块,并且每个工作项负责计算其中一个。我的原始代码通常如下所示:
__kernel void simple_gemm(const __global float4* A,
__read_only image2d_t B,
__global float4* C)
{
// some code to calculate the corresponding piece of matrix C
}
原始内核假设矩阵C可以完美地分成整块,并且在我的设备上最多运行 50 GFLOPS 。然后我添加代码来支持案例,当C分割成片段时,在C的边界上有一些剩余部分,而我的第二个内核看起来像这样:
__kernel void gemm(const __global float4* A,
__read_only image2d_t B,
__global float4* C)
{
if (corresponding_piece_not_on_border)
{
// some code to calculate a whole piece of matrix C
}
else
{
// some code to calculate a partial piece of matrix C
}
}
但是,当我回去测试原始案例时(也就是说,没有边框情况,因此其他代码永远不会被执行),我发现我的内核性能已降至约 30 GFLOPS ,这是不可预期的。我已经仔细检查过我的内核永远不会到达else
块中的代码,这意味着第二个内核在输入原始测试数据时在逻辑上与第一个内核完全相同。
(我尝试获取我的内核的低级代码&#34;以查看是否存在错误,但似乎高通尚未公布其低级别规范)< / p>
那么,在我的情况下可能出现什么问题?任何帮助将不胜感激。