我想将单个 Intel CPU 内核的速度与单个 nVidia GPU 内核的速度(即:单个 CUDA 代码、单个线程)进行比较。我确实实现了以下简单的二维图像卷积算法:
void convolution_cpu(uint8_t* res, uint8_t* img, uint32_t img_width, uint32_t img_height, uint8_t* krl, uint32_t krl_width, uint32_t krl_height)
{
int32_t center_x = krl_width / 2;
int32_t center_y = krl_height / 2;
int32_t sum;
int32_t fkx,fky;
int32_t xx,yy;
float krl_sum = 0;
for(uint32_t i = 0; i < krl_width*krl_height; ++i)
krl_sum += krl[i];
float nc = 1.0f/krl_sum;
for(int32_t y = 0; y < (int32_t)img_height; ++y)
{
for(int32_t x = 0; x < (int32_t)img_width; ++x)
{
sum = 0;
for(int32_t ky = 0; ky < (int32_t)krl_height; ++ky)
{
fky = krl_height - 1 - ky;
for(int32_t kx = 0; kx < (int32_t)krl_width; ++kx)
{
fkx = krl_width - 1 - kx;
yy = y + (ky - center_y);
xx = x + (kx - center_x);
if( yy >= 0 && yy < (int32_t)img_height && xx >= 0 && xx < (int32_t)img_width )
{
sum += img[yy*img_width+xx]*krl[fky*krl_width+fkx];
}
}
}
res[y*img_width+x] = sum * nc;
}
}
}
CPU 和 GPU 的算法相同。我还制作了另一个与上面几乎相同的 GPU 版本。唯一的区别是我在使用它们之前将img
andkrl
数组传输到共享内存。
我使用了 2 张尺寸为 52x52 的图像,我得到了以下性能:
- 中央处理器:10 毫秒
- 图形处理器:1338 毫秒
- GPU (smem): 1165ms
CPU 是 Intel Xeon X5650 2.67GHz,GPU 是 nVidia Tesla C2070。
为什么我会得到这样的性能差异?对于这个特定的代码,单个 CUDA 内核看起来要慢 100 倍!有人可以向我解释为什么吗?我能想到的原因是
- CPU的更高频率
- CPU 进行分支预测。
- CPU可能有更好的缓存机制?
您认为造成这种巨大性能差异的主要问题是什么?
请记住,我想比较单个 CPU 线程和单个 GPU 线程之间的速度。我并不是要评估 GPU 的计算性能。我知道这不是在 GPU 上进行卷积的正确方法。