使用CUDA内核中的许多固定大小的矩阵

Dan*_*iel 6 c++ cuda gpgpu matrix

我希望工作大约4000个固定大小(3x3,4x4)矩阵,做矩阵求逆和特征分解等事情.

在我看来,并行化这种方法的最佳方法是让许多GPU线程中的每一个都在单个问题实例上工作.

有合理的方法吗?我已经阅读:http://www.culatools.com/blog/2011/12/09/batched-operations/但据我所知,它始终是"正在处理"的东西,没有解决方案.三年后,我希望有一个很好的解决方案.

到目前为止,我看过:

  • 在CUDA内核中使用Eigen:http://eigen.tuxfamily.org/dox-devel/TopicCUDA.html.但这还处于起步阶段:因此,似乎效果不好,有些事情没有实施.而且,我不确定它是否针对CUDA进行了优化.几乎没有文档,代码的唯一例子是测试文件(eigen/test/cuda_basic.cu).当我尝试在CUDA内核中使用Eigen时,在内核中声明一个简单的东西Eigen::MatrixXf并不能用nvcc V7.0.27Eigen 3.2.90(mercurial)编译.
  • 使用cuBLAS设备API库在内核中运行BLAS例程.似乎cuBLAS及其同类产品即使对于小型矩阵也要编写并行化,这对于我感兴趣的3x3和4x4矩阵来说似乎有点过分和可能很慢.而且,我不确定是否还有像cuBLAS这样的东西也可以做特征分解或SVD.(据我所知,CULA不支持从内核中调用它的例程).
  • 使用CUDA流批处理内核.在CUDA Toolkit v7.0的cuBLAS文档的第2.1.7节"批处理内核"中,建议使用此方法.但是"""在实践中,不可能同时执行超过16个并发内核""",因此处理4000个小矩阵会很糟糕.在前面提到的CULA博客文章的链接中,我引用,""理论上,人们可以在每个问题上使用CUDA流并一次启动一个问题.由于两个原因,这会表现不佳.首先是每个块的线程数量太低; [...]其次是以这种方式启动数千个操作所产生的开销是不可接受的,因为启动代码与执行代码一样昂贵(如果不是更昂贵) CPU上的矩阵."""
  • 在内核中实现我自己的矩阵乘法和特征分解.这可能非常慢,并且可能另外耗费时间来实现.

在这一点上,我很想放弃在GPU上做这件事.遗憾的是,因为我希望算法的实时性能要求每0.1秒反转4000个3x3矩阵大约100次.

Rob*_*lla 4

cublas 函数getrfBatched和 getriBatched 专为小矩阵的批量求逆而设计。这应该比动态并行或流(您的第二种和第三种方法)更快。此外,批处理求解器以源代码形式提供 ,可以进行矩阵求逆。您需要以注册开发人员身份登录developer.nvidia.com 才能访问此链接。

另外,我不确定是否有类似 cuBLAS 的东西也可以进行特征分解或 SVD。(据我所知,CULA 不支持从内核内部调用其例程)。

Cusolver 提供了一些特征求解器函数。然而,它们不是批处理的,也不能从设备代码中调用,因此您面临着流作为除此之外的唯一选择。