低性能 – 补丁匹配.GPU 上的图像处理 (CUDA)

Low performance – Patch Match. Image Processing on GPU (CUDA)

本文关键字:图像处理 CUDA GPU 性能 补丁      更新时间:2023-10-16

我有一个性能问题:CPU和GPU的性能几乎相同。

我处理的问题是补丁匹配。我有 2 个矩阵。我想找出大矩阵和小矩阵之间的最大相似性在哪里。

矩阵的二进制值为 0/1(黑色和白色)。

当我使用 i5 CPU 检查小矩阵与大矩阵之间的匹配时,需要 30 毫秒(使用多线程)。

当我在 Ge-force GT 730 中检查小矩阵与大矩阵之间的匹配时,也需要 33 毫秒。

我希望 GPU 至少以 1 个数量级的速度更快地工作。我对目前的结果感到非常失望。

我有两个矩阵:

1) 大 - 300000(300 行,1000 列)

2)小50000(50行,1000列)

比较过程是通过将大矩阵分成 250 个子矩阵,然后将每个子矩阵与小矩阵进行比较来完成的,然后找到最高的相似性。

相似性标准是两个矩阵(小矩阵和子大矩阵)上相应的黑色像素之和除以子大矩阵上的黑色像素之和。

我使用以下 CUDA 代码完成了最后一个任务:

__global__ void matCompare_cuda (uint8_t  *D_SUB , uint8_t  *D_SMALL ,  float *D_RSLTS , unsigned int step, int numOfIndentations ,int SUB_size, int SMALL_size)
{
int  i = 0 , j = 0 , success = 0, sumZero = 0;    
int tid = threadIdx.x + blockIdx.x * blockDim.x;
int LoopIndex = ( tid * step );
if (tid < numOfIndentations)            
{
for ( j = 0 ; j < (SMALL_size) ; j++)
{
i = j + LoopIndex;
if ( D_SUB[i] == 0 )
{
{
sumZero++;
if ( D_SMALL[j] == 0 )                
success++;            
}
}
}
if (  success > 0 && sumZero > 500)
D_RSLTS[tid] = 100*((float)success / sumZero) ;                 
}
}

内核发布:

int numOfIndentations = 300-50  //[ (big.row) - (small.row)]
int numBlock = 16;
int threadNumber = numOfIndentations/numBlock;
matCompare_cuda<<< numBlock , threadNumber >>> ( D_SUB , D_SMALL , D_RSLTS , step, numOfIndentations, SUB_size, SMALL_size ); 

中央处理器代码:

for (i=0; i < (pixelNum) ; i++)
{    
if (SUB[i]==0)
{
sumDots = sumDots +1;
if (SMALL->Image[i]==0)
{
success = success + 1;
}    
}
}

if (success>0)
if (sumDots>500)    
RSLT=((float)success/sumDots)*100;

您是否看到GPU代码可以进行任何改进?

有几件事。 如果可能的话,尽量避免使用if。你可以在这里写:

sumZero += (1 - D_SUB[i])
success += (1 - D_SUB[i]) * (1 - D_SMALL[j])

但是,我认为您不会在这里看到巨大的差异。我认为有两个原因。

一是调用 cuda 有开销。数据需要复制到图形卡并返回。这会消耗您获得的一些加速。不确定它是多少,但由于运行时太短,它可以发挥作用。我希望你没有计时内核的编译和其他一次性的东西(通过在循环中运行代码并忽略前几次迭代来将它们取出)。

其次,你的大矩阵太小,你的小矩阵太大。因为小矩阵太大了(1000 列),我猜它与 CPU 缓存行配合得很好。如果小矩阵较小,则必须更频繁地转到下一行,这将增加中断缓存行的机会。GPU 使用矩形进行缓存,因此不会有问题。如果大矩阵更大,你也会增加所需的计算量,这样GPU就会开始领先。