我试图提高慢代码的性能。该代码使用了 cblas,我试图通过使用 magma 和 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);
}