我打算乘以使用缓存友好的方法2点矩阵(这将导致较少的未命中的数目)
我发现,这可以用一个缓存友好置函数来完成。
但我无法找到该算法。 我能知道如何实现这一目标?
我打算乘以使用缓存友好的方法2点矩阵(这将导致较少的未命中的数目)
我发现,这可以用一个缓存友好置函数来完成。
但我无法找到该算法。 我能知道如何实现这一目标?
你正在寻找这个词是颠簸 。 搜索在谷歌颠簸矩阵乘法产生更多的结果 。
针对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];
}
基本上,在大步骤快速度导航存储器是不利的性能。 在乙对于k访问模式[K,J]在做这一点。 因此,而不是在存储跳来跳去,我们可能会重新安排操作,使得最内环仅在矩阵的第二存取操作指数:
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;
}
}
}
@塞萨尔的答案是不正确的。 例如,内环
for (int k = 0; k < n; k++)
s += a[i,k] * Bcolj[k];
经过的第i列。
下面的代码应该确保我们始终一行访问数据行。
void multiply(const double (&a)[I][K],
const double (&b)[K][J],
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;
}
}
}
}