通过在循环内使用cuda内核来降低性能

时间:2019-05-12 20:17:17

标签: cuda magma

我试图改善慢速代码的性能。该代码使用了cblas,我正尝试通过使用岩浆和cuda来提升性能。首先,我刚刚将cblas呼叫传递给了岩浆。但是它在循环内需要CPU <-> GPU副本,因此它使程序的运行速度甚至比cblas版本慢。然后,由于有stackoverflow成员的建议,我开始使用cuda内核,因为这样我可以减少1个副本,从而使性能有所提高。 但是,我的代码仍然比CPU代码慢得多。是由在循环内调用内核引起的吗?有没有一种方法可以避免循环内的所有CPU <-> GPU副本?我开始认为也许这段代码不值得一概而论。

这是我的代码:

__global__ void calculateGamma(double* d_delta, double *d_gamma_xi, double *dotresult, double* gamma_output) {

  int index= blockIdx.x;
  gamma_output[index] = -(*d_gamma_xi + *dotresult)/ *d_delta;
}

for (i=0;i<m-1;i++) {
      if (i==0) {
        gamma = -gamma_x[i+1]/delta;
        cudaMemcpy(d_gammaOutput, &gamma, sizeof(double), cudaMemcpyHostToDevice);
      } else {

        cublasDdot(h, i, &d_gamma_x[1], 1, &(d_l2)[1], 1, dotresult);
        cudaDeviceSynchronize();
        cublasSetPointerMode(h, CUBLAS_POINTER_MODE_HOST);

        calculateGamma<<<1,1>>>(d_delta, &d_gamma_x[i+1], dotresult, d_gammaOutput);
        cudaMemcpy(get_gamma_output, d_gammaOutput, sizeof(double), cudaMemcpyDeviceToHost);

        gamma = *get_gamma_output;
        magma_dcopy(i, &(d_l2)[1], 1, &(d_l1)[2], 1, queue);
        magma_daxpy(i, gamma, &(d_l2)[1], -1, &(d_l1)[2], 1, queue);

        magma_dswap(ny, d_l1, 1, d_l2, 1, queue);
      }
      magma_dcopy(1, d_gammaOutput, 1, &(d_l2)[1], 1, queue);
      delta = gamma_x[0] + magma_ddot(i+1,&d_gamma_x[1],1,&(d_l2)[1],-1, queue);      

      ln_determinant_C += log(delta);
}

1 个答案:

答案 0 :(得分:1)

更新:由于我的GPU不佳,此代码的速度较慢。在GPU上以更好的性能运行它使其运行速度比CBlas版本的代码快得多。