这是对GPU性能的索贝尔滤波吗?
本文关键字:贝尔 GPU 性能 | 更新日期: 2023-09-27 18:18:41
我有一个与CUDA相关的问题要问你:)。由于我对使用CUDA比较陌生,我想知道这个"性能"是否可以。
我正在使用c#和Cudafy.Net!
我有一个灰度图像(表示为float[]),我从屏幕截图中计算(图像的大小是:1920x1018像素)。
现在我使用在GPU上运行的Sobel过滤器(通过Cudafy.Net),看起来像这样:
[Cudafy]
public static void PenaltyKernel(GThread thread, Single[] data, Single[] res, Int32 width, Int32 height)
{
Single[] shared_data = thread.AllocateShared<Single>("shared_data", BLOCK_WIDTH * BLOCK_WIDTH);
///Map from threadIdx/BlockIdx to Pixel Position
int x = thread.threadIdx.x - FILTER_WIDTH + thread.blockIdx.x * TILE_WIDTH;
int y = thread.threadIdx.y - FILTER_WIDTH + thread.blockIdx.y * TILE_WIDTH;
shared_data[thread.threadIdx.x + thread.threadIdx.y * BLOCK_WIDTH] = data[x + y * width];
thread.SyncThreads();
if (thread.threadIdx.x >= FILTER_WIDTH && thread.threadIdx.x < (BLOCK_WIDTH - FILTER_WIDTH) &&
thread.threadIdx.y >= FILTER_WIDTH && thread.threadIdx.y < (BLOCK_WIDTH - FILTER_WIDTH))
{
///Horizontal Filtering (detects horizontal Edges)
Single diffHorizontal = 0;
int idx = GetIndex(thread.threadIdx.x - 1, thread.threadIdx.y - 1, BLOCK_WIDTH);
diffHorizontal -= shared_data[idx];
idx++;
diffHorizontal -= 2 * shared_data[idx];
idx++;
diffHorizontal -= shared_data[idx];
idx += 2*BLOCK_WIDTH;
diffHorizontal += shared_data[idx];
idx++;
diffHorizontal += 2 * shared_data[idx];
idx++;
diffHorizontal += shared_data[idx];
///Vertical Filtering (detects vertical Edges)
Single diffVertical = 0;
idx = GetIndex(thread.threadIdx.x - 1, thread.threadIdx.y - 1, BLOCK_WIDTH);
diffVertical -= shared_data[idx];
idx += BLOCK_WIDTH;
diffVertical -= 2 * shared_data[idx];
idx += BLOCK_WIDTH;
diffVertical -= shared_data[idx];
idx = GetIndex(thread.threadIdx.x + 1, thread.threadIdx.y - 1, BLOCK_WIDTH);
diffVertical += shared_data[idx];
idx += BLOCK_WIDTH;
diffVertical += 2 * shared_data[idx];
idx += BLOCK_WIDTH;
diffVertical += shared_data[idx];
///Convert the "edgyness" for the Pixel and cut off at 1.0
Single diff = GMath.Min(1.0f, GMath.Sqrt(diffHorizontal * diffHorizontal + diffVertical * diffVertical));
///Get the Array-Index
idx = GetIndex(x, y, width);
///Set the Value
res[x + y * width] = diff;
}
}
运行前设置:
TILE_WIDTH = 16;
FILTER_WIDTH = 1;
BLOCK_WIDTH = TILE_WIDTH + 2 * FILTER_WIDTH;
当我运行这个"PenaltyKernel"函数时,包括对数组的内存分配, 将数据复制到设备和设备之间,我的平均运行时间约为6.2ms(使用GTX 680 GT!)。
所以我现在的问题是,如果这个速度是ok的(这将使大约161帧每秒),或者如果我错过了什么?我的索贝尔过滤器还行吗(我的意思是,结果看起来不错:))?
任何帮助都是感激的!
我觉得这个速度还可以。大量的时间来自主机和设备之间的数据复制(特别是从GPU到CPU的传输速度很慢)。
关于速度的说明:一般来说,如果图像很小,GPU上的图像处理可能比CPU上的慢(我没有测试过你的代码,所以我不知道这在你的情况下是否正确)。但是,图像越大,在设备上的处理速度就越快。