【发布时间】:2014-05-28 16:40:24
【问题描述】:
我需要关于如何优化我在 CUDA 中实现 Smith-Waterman 算法的建议。
我要优化的部分是填充矩阵。由于矩阵元素之间的数据依赖性(每个下一个元素都依赖于其他元素 - 向左、向上和向左),我正在并行填充反对角矩阵元素,如图所示下图:
我的程序在循环中运行
int diag = 1;
for(int x = 0; x < size_b; x++)
{
block_size = 1024;
if(block_size > diag)
{
block_size = diag;
}
SAFE_KERNEL_CALL((dev_init_diag<<<(diag - 1)/block_size + 1, block_size>>>(H, size_a, size_b, x,
sequence_a, sequence_b, false, x_offset, y_offset, null_ind)));
diag++;
}
如您所见,每个对角线都有一个内核调用。
因为我有相当大的矩阵(旁边有21000 元素),所以有很多内核调用。结果,我对CUDA内核调用的开销很大,浪费了大约一半的处理时间,这可以从Visual Profiler的截图中看出(看Profiler的开销字符串):
所以,问题是如何摆脱多个内核调用并消除这种开销。
有一件重要的事情需要注意: 我为每个对角线调用一个新内核的原因是我需要在下一次调用之前同步线程和块,据我所知,同步 CUDA 块的唯一方法是完成内核并重新启动它。不过,对于这种算法,可能会有更好的解决方案。
感谢您阅读本文!
/////////////////////////////////////// //////////////
好的,谢谢您的回复! 还有一个问题,更多关于 CUDA 的信息: 所以,我必须实现一个新的内核,大概是这样的:
__global__ void kernel(...)
{
for(int diag_num = 0; diag_num < size; diag_num++)
{
init_one_diag(...);
syncronize_threads();
}
}
但这意味着我只能在一个 cuda 块上启动这个内核?(因为我知道不同块之间没有同步)
在我以这种方式启动内核之前:
dev_init_diag>>(...)
新方法是否会同样有效?
【问题讨论】:
-
你可以试试动态并行?