在 CUDA 内核中使用许多固定大小的矩阵
Working with many fixed-size matrices in CUDA kernels
我希望处理大约 4000 个固定大小(3x3、4x4)矩阵,进行矩阵求逆和特征分解等操作。
在我看来,最好的并行化方法是让许多 GPU 线程中的每一个都处理问题的单个实例。
有什么合理的方法吗?我已阅读:http://www.culatools.com/blog/2011/12/09/batched-operations/ 但据我所知,它总是 "being worked on" 且看不到解决方案。三年过去了,希望有个好的解决办法。
到目前为止,我看过:
- 在 CUDA 内核中使用 Eigen:http://eigen.tuxfamily.org/dox-devel/TopicCUDA.html。但这还处于起步阶段:因此,它似乎运作不佳,有些事情没有实施。此外,我不确定它是否针对 CUDA 进行了优化。几乎没有文档,唯一的代码示例是一个测试文件 (eigen/test/cuda_basic.cu)。当我尝试在 CUDA 内核中使用 Eigen 时,在内核中声明
Eigen::MatrixXf
等简单的事情在使用 nvcc V7.0.27
和 Eigen 3.2.90 (mercurial). 的编译中无法生存。
- 使用 cuBLAS 设备 API 库在内核中 运行 BLAS 例程。似乎 cuBLAS 及其同类产品被编写为即使对于小矩阵也是并行化的,这对于我感兴趣的 3x3 和 4x4 矩阵来说似乎有点矫枉过正并且可能很慢。另外,我不确定是否有类似 cuBLAS 的东西也可以做特征分解或 SVD。 (据我所知,CULA 不支持从内核中调用它的例程)。
- 使用 CUDA 流的批处理内核。在 CUDA 工具包 v7.0 的 cuBLAS 文档的第 2.1.7 "Batching Kernels" 节中,建议这样做。但是“"in practice it is not possible to have more than 16 concurrent kernels executing at the same time"””,因此处理 4000 个小矩阵会很糟糕。在前面提到的 link 到 CULA 博客 post 中,我引用了“”"One could, in theory, use a CUDA stream per problem and launch one problem at a time. This would be ill-performing for two reasons. First is that the number of threads per block would be far too low; [...] Second is that the overhead incurred by launching thousands of operations in this manner would be unacceptable, because the launch code is as expensive (if not more expensive) as just performing the matrix on the CPU."”
- 在内核中实现我自己的矩阵乘法和特征分解。这可能会很慢,而且实施起来可能很耗时。
在这一点上,我很想完全放弃在 GPU 上执行此操作。很遗憾,因为我希望算法的实时性能需要每 0.1 秒反转 4000 个 3x3 矩阵大约 100 次。
可以进行矩阵求逆的 cublas 函数 getrfBatched and getriBatched are designed for batch inversion of small matrices. This should be quicker than either dynamic parallelism or streams (your 2nd and 3rd approaches.) Also a batch solver is available in source code form。您需要在 developer.nvidia.com 以注册开发者身份登录才能访问此 link。
Also, I'm not sure if there is anything like cuBLAS that can also do eigendecomposition or SVD. (As far as I know, CULA does not support calling its routines from within kernels).
Cusolver 提供了一些 eigen solver functions。然而,它们不是批处理的,也不是从设备代码调用的,所以你面临着流作为除此之外的唯一选择。
我希望处理大约 4000 个固定大小(3x3、4x4)矩阵,进行矩阵求逆和特征分解等操作。
在我看来,最好的并行化方法是让许多 GPU 线程中的每一个都处理问题的单个实例。
有什么合理的方法吗?我已阅读:http://www.culatools.com/blog/2011/12/09/batched-operations/ 但据我所知,它总是 "being worked on" 且看不到解决方案。三年过去了,希望有个好的解决办法。
到目前为止,我看过:
- 在 CUDA 内核中使用 Eigen:http://eigen.tuxfamily.org/dox-devel/TopicCUDA.html。但这还处于起步阶段:因此,它似乎运作不佳,有些事情没有实施。此外,我不确定它是否针对 CUDA 进行了优化。几乎没有文档,唯一的代码示例是一个测试文件 (eigen/test/cuda_basic.cu)。当我尝试在 CUDA 内核中使用 Eigen 时,在内核中声明
Eigen::MatrixXf
等简单的事情在使用nvcc V7.0.27
和 Eigen 3.2.90 (mercurial). 的编译中无法生存。
- 使用 cuBLAS 设备 API 库在内核中 运行 BLAS 例程。似乎 cuBLAS 及其同类产品被编写为即使对于小矩阵也是并行化的,这对于我感兴趣的 3x3 和 4x4 矩阵来说似乎有点矫枉过正并且可能很慢。另外,我不确定是否有类似 cuBLAS 的东西也可以做特征分解或 SVD。 (据我所知,CULA 不支持从内核中调用它的例程)。
- 使用 CUDA 流的批处理内核。在 CUDA 工具包 v7.0 的 cuBLAS 文档的第 2.1.7 "Batching Kernels" 节中,建议这样做。但是“"in practice it is not possible to have more than 16 concurrent kernels executing at the same time"””,因此处理 4000 个小矩阵会很糟糕。在前面提到的 link 到 CULA 博客 post 中,我引用了“”"One could, in theory, use a CUDA stream per problem and launch one problem at a time. This would be ill-performing for two reasons. First is that the number of threads per block would be far too low; [...] Second is that the overhead incurred by launching thousands of operations in this manner would be unacceptable, because the launch code is as expensive (if not more expensive) as just performing the matrix on the CPU."”
- 在内核中实现我自己的矩阵乘法和特征分解。这可能会很慢,而且实施起来可能很耗时。
在这一点上,我很想完全放弃在 GPU 上执行此操作。很遗憾,因为我希望算法的实时性能需要每 0.1 秒反转 4000 个 3x3 矩阵大约 100 次。
可以进行矩阵求逆的 cublas 函数 getrfBatched and getriBatched are designed for batch inversion of small matrices. This should be quicker than either dynamic parallelism or streams (your 2nd and 3rd approaches.) Also a batch solver is available in source code form。您需要在 developer.nvidia.com 以注册开发者身份登录才能访问此 link。
Also, I'm not sure if there is anything like cuBLAS that can also do eigendecomposition or SVD. (As far as I know, CULA does not support calling its routines from within kernels).
Cusolver 提供了一些 eigen solver functions。然而,它们不是批处理的,也不是从设备代码调用的,所以你面临着流作为除此之外的唯一选择。