在没有多次启动的情况下将数据流式传输到CUDA内核

时间:2017-10-26 07:50:44

标签: c++ cuda

我正在尝试GPU加速算法,我在3D空间中收到异步粒子流$ p = [x,y,t] $。每个向量$ p_n $需要乘以一堆变换矩阵。由于这些转换是彼此独立的,它们可以并行发生,所以我编写了一个CUDA内核来做到这一点。它工作得很好,但当然对于每个传入的$ p_n $我最终会重新启动CUDA内核。启动CUDA内核会带来很大的时间损失,因此我失去了GPU加速的优势。所以我的问题是,我可以保持内核打开并以某种方式将粒子流式传输到它吗?

如果这里的任何帮助是我当前的内核:

__global__
void project(float *projection_matrix, float *vector, float *output_matrix) {
    int col_index = blockIdx.x * blockDim.x + threadIdx.x;
    int row_index = blockIdx.y * blockDim.x + threadIdx.y;
    int output_index = (col_index*3 + threadIdx.y);
    int transform_first_element = col_index * 9 + threadIdx.y * 3;
    int stride = blockDim.x*blockDim.y*gridDim.x;

    while (output_index < (NUMBER_OF_TRANSFORMS * 3)) {
        output_matrix[output_index] = projection_matrix[transform_first_element]*vector[0]+ projection_matrix[(transform_first_element+1)]*vector[1] + projection_matrix[(transform_first_element+2)]*vector[2];
        output_index += stride;
    }
}

这就是我所说的:

...
project <<<num_blocks_dim, block_dim >>> (transformationList, inputVector, outputMatrix);
cudaDeviceSynchronize();
...

1 个答案:

答案 0 :(得分:1)

您需要将请求批处理为更大的块并在许多粒子上调用内核。您可以使用内核的第三维来迭代它们。一种方法是在内核运行时累积传入的粒子。如果没有足够的粒子来证明内核启动的合理性,请在CPU上处理它们。

如果在GPU上生成粒子,您可以选择使用较新版本的CUDA从内核启动内核,但是仍然需要一个相当大的块才能获得胜利。

如果它们来自CPU然后又回到CPU,我会感到惊讶的是,除非矩阵的数量非常大,否则它可以让它得到回报。 (与优化良好的SIMD CPU代码相比。)

相关问题