免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5816 | 回复: 5
打印 上一主题 下一主题

求助,矩阵相乘的优化? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-11 06:37 |只看该作者 |倒序浏览
大家有什么好的算法介绍一下,昨天看了一段code,区别不大阿,各位指点一下,谢谢

Matrix operator*(const Matrix& B)
{
        int B_M = B.getRow();
        int B_N = B.getColumn();
        if( N!= B_M)
        {
                throw "Dimension for multiplication do NOT match !" ;
        }

        Matrix C(M,N);
        /*-------------------------------------------------------------
        //  Standard implemetion of matrix multiplication formula

        for(int i=0; i<M; i++)
        for(int j=0;j<B_N; j++)
        {     
        C.data[i*N+j]= 0;
        for(int k=0; k<N;k++)
        C.data[i*N+j]+= data[i*N+k]* B.data[k*N+j];
        }
        //----------------------------------------------------------- */

        //-------------------------------------------------------------
        // An optimized way to speed up the multiplication calculation

        for(int i=0, e=0; i<M; i++)
                for(int j=0;j<B_N; j++, e++)
                {   
                        T val = data[i*N] * B.data[j];
                        for(int k=1, c = i * N+1, d = j + B_N; k<N;k++, c++, d += B_N)
                                val += data[c]* B.data[d];

                        C.data[e] = val;
                }               
                //---------------------------------------------------
                return C;
}

论坛徽章:
0
2 [报告]
发表于 2007-01-11 08:55 |只看该作者
测试一下它们的处理器消耗,就知道了。

论坛徽章:
0
3 [报告]
发表于 2007-01-12 05:23 |只看该作者
void dgemm(const Matrix &A, const Matrix &B, Matrix &C)
竟然比
Matrix operator % (const Matrix &a, const Matrix &b)
慢了好多。
operator overloading用的是最基本的算法,return 一个matrix,
而dgemm是pure pointer access但是多了一个loop.
怎么回事啊?好多人都说pure access要快一些,高手指点一下啊。



Matrix operator % (const Matrix &a, const Matrix &b)
{
#ifdef DEBUG__
        if (a.ncol_ != b.nrow_)
                errorReport("(Matrix operator %) : matrices do not conform in multiplication");
#endif

        Matrix c(a.nrow_, b.ncol_);
        double *ptr_a = a.data_, *ptr_b = b.data_, *ptr_c = c.data_;
        double sum;
        for (int i = 0; i < a.nrow_; i++)
                for (int j = 0; j < b.ncol_; j++)
                {
                        sum = 0.0;
                        for (int k = 0; k < a.ncol_; k++)
                                sum += ptr_a[i*a.ncol_+k]*ptr_b[k*b.ncol_+j];
                        ptr_c[i*c.ncol_+j]=sum;
                }

                return c;
}



void dgemm(const Matrix &A, const Matrix &B, Matrix &C)
// A[m][n] * B[n][l] = C[m][l]
{  
        int i, k, j;
        const double *ptr_a = A.data();
        int m = A.nrows(), n = A.ncols(), l = B.ncols();

        for ( i = 0; i < m; i++ )
        {  
                double *ptr_c = C.data() + i*l, Aik = *ptr_a++;
                const double *ptr_b = B.data();

                for ( j = 0; j < l; j++ )
                        *ptr_c++ = Aik * (*ptr_b++);

                for ( k = 1; k < n; k++ )
                {  
                        ptr_b  = B.data() + k*l;
                        ptr_c  = C.data() + i*l;
                        Aik = *ptr_a++;

                        for ( j = 0; j < l; j++ )
                        {  
                                *ptr_c++ += Aik * (*ptr_b++);  
                        }
                }
        }
}

论坛徽章:
0
4 [报告]
发表于 2007-01-12 10:27 |只看该作者
这个只有看编译后的汇编代码了,不过用数组下标访问和用指针,在现在的编译器里也没啥区别

论坛徽章:
0
5 [报告]
发表于 2007-01-12 11:04 |只看该作者
1. 两个矩阵相乘请参考斯特拉森(V.Strassen)乘法;
2. 多个矩阵连乘请参考矩阵连乘的动态规划算法(就是加括号确定一个最优计算顺序,不处理和处理的效率往往相差非常大!)
这些都可以在讲解算法的书中找到,另外可以参考:
线性代数与多项式的快速算法,游兆主编,上海科学技术出版社,1980(这本书我没看过,是算法书上在讲解矩阵乘法时推荐的,据说对矩阵相乘做了深入讨论)

论坛徽章:
0
6 [报告]
发表于 2007-01-12 11:44 |只看该作者
要比较彻底一点的优化就用FFT吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP