如何提高CUDA中needleman -wunsch算法的性能

时间:2015-04-23 16:23:38

标签: algorithm cuda gpu gpu-programming

我需要就如何在CUDA中优化Needleman-Wunsch算法的实现提出建议。

我想优化我的代码以填充CUDA中的DP矩阵。由于矩阵元素之间的数据依赖性(每个下一个元素依赖于其他元素 - 离开它,直到它,并且离开它),我按如下方式并行填充反对角矩阵元素:

__global__ void alignment_kernel(int *T, char *A, char *B, int t_M, int t_N, int d) {
  int row = BLOCK_SIZE_Y * blockIdx.y + threadIdx.y;
  int col = BLOCK_SIZE_X * blockIdx.x + threadIdx.x;

  // Check if we are inside the table boundaries.
  if (!(row < t_M && col < t_N)) {
    return;
  }

  // Check if current thread is on the current diagonal
  if (row + col != d) {
    return;
  }

  int v1;
  int v2;
  int v3;
  int v4;
  v1 = v2 = v3 = v4 = INT_MIN;

  if (row > 0 && col > 0) {
    v1 = T[t_N * (row - 1) + (col - 1)] + score_matrix_read(A[row - 1], B[col - 1]);
  }
  if (row > 0 && col >= 0) {
    v2 = T[t_N * (row - 1) + col] + gap;
  }
  if (row >= 0 && col > 0) {
    v3 = T[t_N * row + (col - 1)] + gap;
  } 
  if (row == 0 && col == 0) {
    v4 = 0;
  }

  // Synchronize (ensure all the data is available)
  __syncthreads();

  T[t_N * row + col] = mmax(v1, v2, v3, v4);
}

然而,我的代码的一个明显问题是我做了多个内核调用(代码如下)。到目前为止,我还不知道如何使用线程同步处理反对角线而不这样做。我认为这是达到更好表现的主要问题。

// Invoke kernel.
  for (int d = 0; d < t_M + t_N - 1; d++) {
    alignment_kernel<<< gridDim, blockDim >>>(d_T, d_A, d_B, t_M, t_N, d);
    //CHECK_FOR_CUDA_ERROR();
  }

如何并行处理反对角线,也许使用共享内存来提高加速度?

除了这个问题,还有什么办法可以并行执行needleman-wunsch算法的后跟踪步骤吗?

1 个答案:

答案 0 :(得分:1)

我目前正在研究Needleman Wunsch算法的并行实现(用于基因组映射器)。根据您将要执行的对齐次数,每个线程执行单个对齐可能更有效。

但是,这里是publication并行执行单个对齐(在GPU上)。他们的方法的新颖之处在于它不是通过对角线顺序生成矩阵。他们没有谈论他们如何在他们的出版物中回溯。它们在生成后将矩阵发送回主机,然后使用CPU执行回溯。我认为由于分支,在GPU上的回溯将非常低效。