| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1026 人关注过本帖
标题:高性能矩阵乘代码编写问题
只看楼主 加入收藏
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:10 
因为你多了 3*N*N*N 次乘法以及多了3*N*N*N次加法,所以效率低下

应该用如下方法:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    double **A;
    int row;
    int colum;
}matrix;

matrix* malloc_matrix(int row,int colum)
{
    int i,j;
    matrix *m = (matrix *)malloc(sizeof(matrix));
    m->row = row;
    m->colum = colum;
    m->A = (double **)malloc(row*sizeof(double *));
    for (i=0;i<row ;i++ )
        m->A[i] = (double *)malloc(colum*sizeof(double));
    return m;
}
void free_matrix(matrix *p)
{
    int i;
    for (i=0;i<p->row ;i++ ) free(p->A[i]);
    free(p->A);
    free(p);
}

matrix* multply(const matrix *A,const matrix *B)
{
    int i,j,k;
    if (A->colum != B->row){printf("Row A and colum B must be equal!\n");exit(1);};

    matrix *C = malloc_matrix(A->row,B->colum);
    for (i=0;i<C->row ;i++ )
        for (j=0;j<C->colum ;j++ )
         {
            C->A[i][j]=0.0;
            for (k=0;k<A->colum ;k++ )
                 C->A[i][j] = C->A[i][j] + (A->A[i][k])*(B->A[k][j]);
         }
    return C;
}


int main(int argc, char **argv)
{
    matrix *A = malloc_matrix(3,4);
    matrix *B = malloc_matrix(4,3);
    matrix *C;

    int i, j;

    //check
    for (i =0;i<A->row;i++ )
        for (j=0;j<A->colum ;j++ )
            A->A[i][j] = i+1.00*j;

    for (i =0;i<B->row;i++ )
        for (j=0;j<B->colum ;j++ )
             B->A[i][j] = i+2.00*j;

    C = multply(A,B);

    for (i = 0;i<C->row ;i++ )
    {
        for (j=0;j<C->colum ;j++ )
            printf("%f\t",C->A[i][j]);
        printf("\n");
    }

    free_matrix(A);
    free_matrix(B);
    free_matrix(C);
}


人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-03-10 14:30
traz_
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2010-3-8
收藏
得分:0 
非常感谢楼上分享的代码
我原来问题算的是性能(也就是gflops) ,假设矩阵i,j,k的规模为M*N*K,那么矩阵乘算法的主要操作就是在C=A*B+C;中包含的一次乘法和一次加法,
这样总得运算量应该至少为2×M×N×K次,然后用系统提供的时间函数测出multy函数的运行时间t,(2×M×N×K)/ t 换算下单位就可以得到gflops
而且矩阵的规模一般都很大,还要考虑访存的延迟,所以不做循环展开之类的优化操作,性能是不会很好的。。。。。。
2010-03-10 16:50
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:0 
不懂 循环展开之类的优化操作是啥意思,

如果说的是像matlab那样的向量乘法的话就算了,它们内部用到的的依然是循环。
包括fortran里的向量乘法,里面依然还是循环。

所以上面的代码应该块到C的极限了(条件是一个cpu)

当然,现在矩阵乘法很多采用了多线程方法。可以有数倍的效率提高。
建议楼主考虑多线程。

如果还要继续优化的话就只有用fortran 或汇编了.....

希望对楼主有用

人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-03-10 17:23
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:0 
还有,个人经验: 地址访问 和 浮点乘法运算用的时间不在一个数量级别(可能有待继续验证),所以基本上可以忽略地址访问所用的时间

人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-03-10 17:28
traz_
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2010-3-8
收藏
得分:0 
非常感谢 我想C也的确是不能再提升了,我目前还是考虑单cpu呵呵

2010-03-10 19:50
快速回复:高性能矩阵乘代码编写问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.110433 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved