回答
你正在寻找的词是颠簸。在Google yields more results中搜索颠簸矩阵乘法。
对于C的标准乘算法= A * B看起来像
void multiply(double[,] a, double[,] b, double[,] c)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
C[i, j] += a[i, k] * b[k, j];
}
基本上,在大步骤快速度导航存储器是不利的性能。 B中的k的访问模式正在完成该操作。因此,而不是在存储跳来跳去,我们可能会重新安排操作,使得最内环仅在矩阵的第二存取操作指数:
void multiply(double[,] a, double[,] B, double[,] c)
{
for (i = 0; i < n; i++)
{
double t = a[i, 0];
for (int j = 0; j < n; j++)
c[i, j] = t * b[0, j];
for (int k = 1; k < n; k++)
{
double s = 0;
for (int j = 0; j < n; j++)
s += a[i, k] * b[k, j];
c[i, j] = s;
}
}
}
这是该网页上给出的例子。但是,另一种方法是事先将B [k,*]的内容复制到数组中,并在内部循环计算中使用该数组。这种方法通常比替代方案快,即使它涉及复制数据。即使这看起来可能与直觉相反,请随时尝试一下。
void multiply(double[,] a, double[,] b, double[,] c)
{
double[] Bcolj = new double[n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < n; k++)
Bcolj[k] = b[k, j];
for (int i = 0; i < n; i++)
{
double s = 0;
for (int k = 0; k < n; k++)
s += a[i,k] * Bcolj[k];
c[j, i] = s;
}
}
}
@ Cesar的回答不正确。例如,内部循环
for (int k = 0; k < n; k++)
s += a[i,k] * Bcolj[k];
经过a的第i列。
以下代码应确保我们总是按行访问数据。
void multiply(const double (&a)[I][K],
const double (&b)[K][J],
const double (&c)[I][J])
{
for (int j=0; j<J; ++j) {
// iterates the j-th row of c
for (int i=0; i<I; ++i) {
c[i][j] = 0;
}
// iterates the j-th row of b
for (int k=0; k<K; ++k) {
double t = b[k][j];
// iterates the j-th row of c
// iterates the k-th row of a
for (int i=0; i<I; ++i) {
c[i][j] += a[i][k] * t;
}
}
}
}
你的代码也是错的。 c [i] [j]的重置可以是完全可选的(取决于调用者是否将矩阵重置为零)。另外k上的循环从1开始,但应该从零开始。 – greywolf82
@ greywolf82 c [i] [j]需要重置,因为“c [i] [j] + = a [i] [k] * t”的积累需要一个初始值。 “k从0开始”是正确的。固定。 –
是的,我知道,但是如果调用者将memset设置为0,则不需要该循环。在你的代码中添加一条评论来澄清。 – greywolf82
- 1. 相乘两个矩阵
- 2. 相乘以矩阵
- 3. 相乘两个非稀疏矩阵
- 4. 矩阵相乘两个列表与式
- 5. 乘以矩阵的两个元素
- 6. Matlab - 将矩阵乘以3D矩阵的每个矩阵
- 7. 在Java中乘以两个矩阵
- 8. 在R中乘以两个矩阵
- 9. 在R中乘以两个矩阵
- 10. 在Julia中乘以两个矩阵
- 11. 缓存友好的C++在C++中对矩阵进行操作?
- 12. 如何将两个矩阵的列与所有组合相乘
- 13. 将矩阵乘以向量
- 14. 将矢量与矩阵的列相乘的最佳方法
- 15. 缓存不友好的循环超过缓存友好循环的2d阵列
- 16. 3D矩阵乘以2D矩阵的元素明智乘法
- 17. (emu8086)将3x3矩阵与阵列相乘
- 18. SSE矩阵,矩阵乘法
- 19. 矩阵乘法
- 20. 矩阵乘法
- 21. 矩阵乘法
- 22. 矩阵乘法
- 23. 使用管道将两个矩阵相乘
- 24. 将矩阵的每列乘以另一个矩阵
- 25. 将两个矩阵乘以一个矢量
- 26. 矩阵的乘法
- 27. 的矩阵乘法
- 28. N次方矩阵乘法.Better方法
- 29. 矩阵乘法与使用真相法
- 30. 缓存友好阵列迭代图案
在你的第二个代码块'c [i,j] = s;',但似乎'j'没有在该范围内声明。 –
我想知道为什么这是被接受的答案,K上的内部循环正在按列访问,从性能角度看完全错误。 – greywolf82
该代码假设一个类似C的语言,其中矩阵是行主要的。当使用'''a [i,j]''访问以行优先顺序存储的矩阵时,如果你想要'''''''最大化性能。 – Cesar