C中的矩阵表示

时间:2013-11-03 09:33:37

标签: c matrix matrix-multiplication

我想找出C编程语言中m x n实矩阵的最佳表示。

矩阵表示作为单个指针的优点是什么:

double* A;

使用此表示法可以分配内存:

A = (double* )malloc(m * n * sizeof(double));

在这种表示中,矩阵访问需要额外的乘法:

aij = A[i * m + j];

矩阵表示作为双指针有什么缺点:

double** B;

内存分配需要一个循环:

double** B = (double **) malloc(m * sizeof(double*));
for (i = 0; i < m; i++)
    A[i] = (double *) malloc(n * sizeof(double))

在这种表示中你可以使用直观的双索引`bij = B [i] [j],但是有一些缺点会影响性能。我想知道在性能方面什么是最好的演示。

这些矩阵应该用于数值算法,例如奇异值分解。我需要定义一个函数:

void svd(Matrix A, Matrix U, Matrix Sigma, Matrix V);

我正在寻找代表Matrix的最佳方式。如果有任何其他有效的方法来表示C中的矩阵,请告诉我。

我已经看到大多数人使用单指针表示。我想知道是否有一些性能优势而不是双数组表示?

2 个答案:

答案 0 :(得分:5)

查看所需的内存访问。

对于单指针案例,您有:

  1. 读取指针(基地址),可能来自寄存器
  2. 读取四个整数,可能是从寄存器或硬编码到指令集。对于array[i*m+j],4个值为imjsizeof(array[0])
  3. 乘以并添加
  4. 访问内存地址
  5. 对于双指针案例,你有:

    1. 读取指针(基地址),可能来自寄存器
    2. 读取索引,可能来自寄存器
    3. 将索引乘以指针的大小并添加。
    4. 从内存中获取基地址(不太可能是一个寄存器,可能在运行缓存中)。
    5. 读取另一个索引,可能来自寄存器
    6. 乘以对象的大小并添加
    7. 访问内存地址
    8. 您必须访问两个内存位置这一事实可能使双指针解决方案比单指针解决方案慢得多。显然,缓存至关重要;这就是访问数组非常重要的一个原因,这样访问对缓存友好(因此您可以尽可能频繁地访问相邻的内存位置)。

      你可以在我的大纲中挑选细节,一些'乘法'操作可能是移位操作等,但是一般概念仍然存在:双指针需要两次内存访问,而一次是单指针解决方案,那会慢一点。

答案 1 :(得分:0)

以下是一些关于行主要格式的文章。

http://en.wikipedia.org/wiki/Row-major_order

http://fgiesen.wordpress.com/2011/05/04/row-major-vs-column-major-and-gl-es/

这些是CUDA编程中的常见结构;因此我感兴趣。