Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 就地Cholesky反演_C++_Arrays_Matrix_Cuda - Fatal编程技术网

C++ 就地Cholesky反演

C++ 就地Cholesky反演,c++,arrays,matrix,cuda,C++,Arrays,Matrix,Cuda,我想知道是否有可能在不需要临时数组的情况下通过Cholesky分解得到矩阵的逆。到目前为止,我可以在不使用临时数组的情况下获得cholesky分解,但是从那里我还没有找到一种方法来获得原始矩阵的逆矩阵,而不需要重复使用与原始矩阵维数相同的临时矩阵。也就是说,解决这个系统 A x_i = e_i, where e_i is the i-th column if the identity matrix. 实际上,我遵循的是一种稍微好一点的方法,如中所述 一些背景: 我正在编写一个(C/C++)CU

我想知道是否有可能在不需要临时数组的情况下通过Cholesky分解得到矩阵的逆。到目前为止,我可以在不使用临时数组的情况下获得cholesky分解,但是从那里我还没有找到一种方法来获得原始矩阵的逆矩阵,而不需要重复使用与原始矩阵维数相同的临时矩阵。也就是说,解决这个系统

A x_i = e_i, where e_i is the i-th column if the identity matrix.
实际上,我遵循的是一种稍微好一点的方法,如中所述

一些背景: 我正在编写一个(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];
通过这种方式,您将增强内存访问模式,并且只使用1X而不是16x来访问内存。你可能认为全局记忆是个坏主意,但相信我,事实并非如此。你可以回到我发表的关于在GPU上进行人脸检测的论文,阅读更多关于内存访问模式的内容


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

这可能是一种前进的方式,然而,要改变我现在的并行化方案真的很难,调试起来可能很难。但是,很多在CUDA上攻读DNA和蛋白质博士学位的同事并不相信这会有回报,直到我们改变了它,算法所需的时间从36秒减少到了0.54秒。请阅读我所指论文的GPU架构部分,为了更好地理解不同记忆类型之间的平衡,我花了更长的时间阅读了你的论文。我已经在尽可能地进行联合内存访问了。我的问题更多的是关于改变算法的意义,以及如何减少内存的使用和访问。实际上,您根本没有在代码中创建合并模式。减少内存访问次数不是目标,真正的目标是减少未恢复模式或将频繁访问的数据移动到局部变量。另一方面,由于寄存器文件大小有限,大量使用局部变量会导致调度器以多个周期执行扭曲。我很高兴在Skype“mahmoudfayezahmed”上讨论这个问题