我想知道是否有可能通过Cholesky因式分解获得矩阵逆,而无需临时数组。到目前为止,无需使用临时数组就可以进行cholesky分解,但是从那以后,我还没有想出一种方法来获取原始矩阵的逆,而又不使用与原始维相同的临时矩阵。也就是说,解决系统

A x_i = e_i, where e_i is the i-th column if the identity matrix.


我实际上遵循的是http://arxiv.org/abs/1111.4144中所述的更好的方法

一些背景:

我正在编写一个(C / C ++)CUDA程序,其中每个线程都会计算相对较小的(20x20,在某些情况下为40x40)协方差矩阵的逆和行列式,以及其他任务。在CUDA中使用数组的速度不是很快,这就是为什么我想尽量减少使用它们。当我编写原位cholesky因式分解并限制仅使用矩阵的较低项时,我已经看到了一些重大改进,这就是为什么如果我希望在方程式求解中摆脱临时数组的情况,我希望得到一些改进部分,即,如果算法使用临时变量(至少在较小的数组中),则可以。

我知道计算出x = A^{-1} b,正是我最终要做的,通过求解系统A x = b比计算逆数更有效。但是,由于我也需要在Cholesky分解中获得的行列式,因此我认为计算逆函数会更好。

最佳答案

我不确定我要说的内容是否对您有帮助。但是在CUDA中访问阵列的成本是16倍,而成本只有1倍。这取决于每个线程将执行的内存安排和访问模式。

对我来说,我有100个线程,每个线程需要一个20x20整数/浮点数的矩阵。如果我是您,那么您会毫不犹豫地使用所有线程之间共享的一个数组,并且每个线程都将像这样访问第一个元素:

int iFirstElement = gArray[tid]; // where tid is the thread idx assuming this 1D,2D, or 3D I am sure you can calculate the tid easily.
//to access the second element you can use this:
int iSecondElement = gArray[numOfThreads * 1 + tid];
// to access the third element you can use this
int iSecondElement = gArray[numOfThreads * 2 + tid];


这样,您将增强内存访问模式,并且仅消耗1倍而不是16倍来访问内存。您可能会认为全局内存不是一个好主意,但请相信我不是。您可以返回我发表的论文,该论文在GPU上进行人脸检测,以了解有关内存访问模式的更多信息。

http://ijces.org/media/1Iss8-IJCES0402603_v4_iss2_47-55.pdf

最后,局部变量的广泛使用将导致调度程序在多个周期中运行该块,因为每个块的寄存器文件不足以同时运行整个块。

07-24 16:06