我正在对gpu进行一些非常基本的图像处理。我传递一个填充了一个接一个存储的像素RGB值的数组。
我像
一样启动我的内核kernel<<<numBlocks,numThreadsPerBlock>>>(unsigned char * imageData, int val)
网格大小取决于我的图像有多大,但通常会像数千块512-1024个线程一样
在内核中,我做了一些基本的计算,并直接从全局内存中比较值。
int blueIdx = (blockIdx.x * blockDim.x + threadIdx.x) * 3;
int greenIdx = blueIdx + 1;
int redIdx = greenIdx + 1;
float ypx = 0.299 * imageData[redIdx] + 0.587 * imageData[greenIdx] + 0.114 * imageData[blueIdx];
if( ypx > val)
imageData[blueIdx] = 255;
有没有办法优化这种类型的访问?基本上从2d数组中读取值,执行简单的静态乘法,执行比较,然后将新值保存回全局内存。
我已尝试过共享内存但我的实现速度较慢。我假设,因为线程是独立的共享内存将无济于事。
答案 0 :(得分:1)
我还没有尝试过,但依赖于使用uchar3
甚至uchar4
(对于32位对齐)的编译器的聪明性(即缺少它)可能会更快。我必须查看它为内核生成的PTX代码以确保。
int idx = blockIdx.x * blockDim.x + threadIdx.x;
uchar3 rgb = imageData[idx];
float ypx = 0.299 * rgb.x + 0.587 * rgb.y + 0.114 * rgb.z;
if( ypx > val) {
rgb.z = 255;
imageData[idx] = rgb;
}
请注意,只有一个读操作。它只是没有比这更简单。好吧,由于更容易合并,将写操作移出条件分支可能会更快,但由于更多的写操作,它也可能更慢。实验
但实际上,事情应该非常快。我假设您可以在现代游戏GPU上以大约5-10毫秒的速度在1GB数据上运行此内核。这对你来说太慢了吗?你确定内核需要太长时间吗?