Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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语言中的矩阵表示_C_Matrix_Matrix Multiplication - Fatal编程技术网

C语言中的矩阵表示

C语言中的矩阵表示,c,matrix,matrix-multiplication,C,Matrix,Matrix Multiplication,我想找出在C语言中m x n实矩阵的最佳表示形式 矩阵表示作为单个指针有哪些优点: double* A; double** B; 使用此表示法,您可以分配内存: A = (double* )malloc(m * n * sizeof(double)); 在这种表示中,矩阵访问需要额外的乘法: aij = A[i * m + j]; 矩阵表示法作为双指针有哪些缺点: double* A; double** B; 内存分配需要一个循环: double** B = (double **)

我想找出在C语言中m x n实矩阵的最佳表示形式

矩阵表示作为单个指针有哪些优点:

double* A;
double** B;
使用此表示法,您可以分配内存:

A = (double* )malloc(m * n * sizeof(double));
在这种表示中,矩阵访问需要额外的乘法:

aij = A[i * m + j];
矩阵表示法作为双指针有哪些缺点:

double* A;
double** B;
内存分配需要一个循环:

double** B = (double **) malloc(m * sizeof(double*));
for (i = 0; i < m; i++)
    A[i] = (double *) malloc(n * sizeof(double))
我正在寻找表示矩阵的最佳方法。如果有其他有效的方法用C表示矩阵,请告诉我


我看到大多数人使用单指针表示。我想知道与双数组表示相比,是否有一些性能优势?

查看所需的内存访问

对于单指针情况,您有:

  • 可能从寄存器读取指针(基址)
  • 读取四个整数,可能来自寄存器或硬编码到指令集。对于
    数组[i*m+j]
    ,4个值是
    i
    m
    j
    sizeof(数组[0])
  • 乘法和加法
  • 访问内存地址
  • 对于双指针情况,您有:

  • 可能从寄存器读取指针(基址)
  • 读取索引,可能是从寄存器读取
  • 将索引乘以指针的大小并相加
  • 从内存中获取基址(不太可能是寄存器,可能运气好就在缓存中)
  • 读取另一个索引,可能来自寄存器
  • 乘以对象的大小并相加
  • 访问内存地址
  • 必须访问两个内存位置的事实可能会使双指针解决方案比单指针解决方案慢一些。显然,缓存将是至关重要的;这就是为什么访问阵列非常重要的一个原因,以便访问对缓存友好(以便尽可能多地访问相邻的内存位置)


    在我的大纲中,你可以挑剔细节,有些“乘法”运算可能是移位运算等,但一般的概念仍然是:双指针需要两次内存访问,而单指针解决方案需要一次内存访问,这会更慢。

    这里有几篇关于行主格式的文章


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

    您缺少访问矩阵中特定数字并分配矩阵本身的示例代码,因此无法说出您所指的矩阵表示。(不是我投了反对票。)你能告诉我这是否更好,或者我应该删除这个问题吗?在第二种情况下,你可以将Malloc的数量减少到2个甚至1个。也就是说,您可以将一个大的
    double*
    块(与第一个变量中的长度相同)分配给
    A[0]=malloc\u结果
    A[1]=malloc\u结果+n
    A[2]=malloc\u结果+2*n
    等等(假设
    malloc\u结果的类型为
    double*
    )。使用一个malloc,您分配
    sizeof(double*)*m+sizeof(double)*n*m
    ,并分配
    A=malloc\u结果
    A[0]=(double*)(malloc\u结果+m)
    A[1]=A[0]+n
    A[2]=A[1]+n
    等等(假设
    malloc结果的类型为
    (double**)。没有必要进行m+1分配。尽管这些变体有一个缺点,即
    valgrind
    无法检测越界数组访问:因为
    a[0][n]
    只是
    a[1][0]
    尝试分配给它并不是一个错误。