我在将两个尺寸为 5000x1024 的矩阵相乘时遇到问题。我试图以传统的方式通过循环来完成它,但它需要很长时间。有没有实现和优化矩阵运算的好库,或者没有3个循环的算法?
2 回答
您是否考虑过使用 OpenCL?Cloo(C# OpenCL 库)发行版中的一个示例是大型 2D 矩阵乘法。
与 CUDA 不同,OpenCL 内核将在您的 GPU(如果可用且受支持)或 CPU 上运行。在 GPU 上,您会看到非常、非常、非常显着的速度提升。我的意思是,非常戏剧化,大约 10 倍到 100 倍,这取决于你的内核的效率和你的 GPU 有多少内核。(基于 Fermi 的 NVidia 卡将有 384-512 之间,而新的 600 有大约 1500。)
如果你对走这条路不感兴趣——尽管任何做像这样的数字密集型、易于并行化操作的人都应该使用 GPU——确保你至少使用了 C# 的内置并行化:
Parallel.For(
0
,5000
, (i) => {
for(var j=0;j<1024;j++)
{
result[i,j] = .....
}
);
另外,请查看 GPU.NET 和 Brahma。Brahma 允许您使用 LINQ 在 C# 中构建 OpenCL 内核。肯定会降低学习曲线。
看看Strassen 算法,它的运行时间约为。O(n 2.8 ) 而不是 O(n 3 ) 用一种简单的矩阵相乘方法。一个问题是它并不总是稳定的,但在非常高的维度上工作得很好。此外,它真的很复杂,所以我建议您重新考虑您的设计,并可能减小矩阵的大小或将您的问题分成更小的部分。
但请记住,没有特殊属性的矩阵乘法(如Aidan提到的)几乎不可能优化。这里有一个例子:Coppersmith-Winograd 算法需要 O(n 2.3737 ),它是迄今为止最好的矩阵乘法算法之一!最好的选择是使用 OpenCL 和 GPU(由David提到),或者查看其他优化的编程语言,例如带有包的 Python numpy
。
祝你好运!