由于程序可能需要进行复杂的矩阵计算(上千维的矩阵乘法),在用普通的c++代码来跑的时候,耗时无法接受。在matlab上尝试同样的计算,快很多。 请问在算法相同的前提下,是否有办法大幅度提高运算速度。现在尝试尽量避免调用子函数,比如以前取数用GetElement,现在直接把GetElement里的代码放在乘法运算里,的确能快很多。但是还是无法达到满意的速度。 想请问一下是不是因为c++语言的原因导致的计算速度的不足,如果矩阵乘法运算直接用汇编写,然后在vc里调,不知道是不是会有提升?

解决方案 »

  1.   

    汇编可以提高一定的速度,但大大提高速度的还是使用CPU的多媒体指令集MMX,SSE等。
      

  2.   

    主要还是你的算法,算法不好 用汇编也没辙.....
    汇编速度>C>C++>vc(vc写的c++程序已经没有标准c++的效率了)另外就是内存的管理,STL运用不好 会极大的降低运行速度
      

  3.   

    算法上有所谓的好的算法,但大多是空间换时间的思想,可是面对已经非常庞大的空间(10的六次方个double...) 再次的扩大空间,反而会导致时间上的损失,这里面已经有矛盾存在了我觉得,所以暂时没有从算法角度入手考虑问题。想想其实就是两块内存 之间的乘法运算,直接用汇编操作内存的效率是不是比c++操作的效率要高?
      

  4.   

    现在的类里,没啥STL,就纯粹一块内存,速度也是很慢。
      

  5.   

    matlab 应该比 c++慢很多,你的算法有问题,估计代码从matlab转c++而来,字串不要不要用CString, 直接用char *,不要不停的new del
      

  6.   

    首先
    matlab就是C++写的吧
    然后
    这种数值计算最好上Fortran
    最后
    既然matlab快可以把matlab的m文件打包成C++的dll么
      

  7.   

    主要应该还是你的算法问题,如果采用相同的算法的话matlab效率基本不会比cpp高的
      

  8.   

    在matlab上矩阵计算,matlab内部作了优化,也就是说matlab内部的算法也是c或c++的,你自己编写的算法没有优化,虽然代码一样,但人家内部用了另外的算法处理,例如分而治之等,matlab的软件作者做了大量的工作,也可能内部查表等得到结果,你的代码当然不能和他比的。除非你有更好的算法。
      

  9.   

    建议:1.不要采用STL,如果vector ,而是采用动态数组
         2. 采用多线程的方式
         3.优化算法,如将矩阵分块
         
      

  10.   

    像这种高强度的科学计算c/c++是首选,老家伙们用FORTRAN,到现在FORTRAN仍然是重要的解决手段。汇编想都不要想了。
    如果你的C/C++比MATLAB还慢,好好分析一下你的程序吧。真正想解决这类问题的方案是GPGPU, CUDA可以用,但是怕将来英伟达发展不长远。微软的Direct Compute已经能用了,目前双精度浮点运算还有一点问题。GPU特别适合你这种矩阵变换类计算,一个好一点的显卡可以将性能提高几十到上百倍。
    还有一个方案是多核,OpenMP在VS2005以后就加上了,现在已经算比较成熟。把计算机的几个核心都开起来性能提高个一两倍还是比较可行的。
      

  11.   

    矩阵乘法的普通算法的代码,好像也没什么特别的吧,我的如下,大侠们看看,有什么影响效率的地方:
    CMatrix CMatrix::operator*(const CMatrix& other) const
    {
    ASSERT (m_nNumColumns == other.GetNumRows());

    CMatrix result(m_nNumRows, other.GetNumColumns());
    double value; for (int i = 1 ; i <= result.GetNumRows(); ++i)
    {
    for (int j = 1 ; j <= other.GetNumColumns(); ++j)
    {
    value = 0.0 ;
    for (int k = 1 ; k <= m_nNumColumns; ++k)
    {
    value += GetElement(i, k) * other.GetElement(k, j);
    }
    result.SetElement(i, j, value);
    }
    }
      return result;
    }
    改用下面这段后,效率提高了些,但还是远远慢于matlab:
    ASSERT(m_nNumColumns == other.GetNumRows()); // construct the object we are going to return
    CMatrix mtxRet(m_nNumRows, other.GetNumColumns()); int i,j,k;
    int pos1=0,pos2=0,pos3=0;
    for (i = 0 ; i <mtxRet.m_nNumRows ; ++i)
    { for ( j = 0 ; j < mtxRet.m_nNumColumns; ++j)
    {
    pos2=0;
    for (k = 0 ; k < other.m_nNumRows; ++k)
    {
    mtxRet.m_pData[j + pos1] += (this->m_pData[k + pos3])* (other.m_pData[j + pos2]);              
      pos2  +=other.m_nNumColumns;
    }

    } pos1 += mtxRet.m_nNumColumns;
            pos3 +=this->m_nNumColumns;
    }

      return mtxRet ;
      

  12.   

    一般一个3000*3000的矩阵相乘,matlab大约4秒钟可以,这段代码需要30秒左右。而如果是30*3000 乘以
    3000*3000的,matlab是十毫秒级,这段程序也是秒级的。  效率差距还是很大的。
    说matlab慢的,先动手做做实验,看看吧
      

  13.   

    不懂,是否换成C,一般高效算法都是用C写的,不是c++。
      

  14.   

    一般一个3000*3000的矩阵相乘,matlab大约4秒钟可以,这段代码需要30秒左右。而如果是30*3000 乘以
    3000*3000 的,matlab是十毫秒级,这段程序也是秒级的。 效率差距还是很大的。是 matlab 内部有另外的算法。这是别人的程序员做了相当长的工作。换个说法,你就是用汇编也没人家的快。唯一可以做到的就是作弊(查表)。例如 x=1000+999+...+1; y= 2000+1999+...+1.求x+y=?;如果它保存有10000+9999+...+1的所有的结果,那么 x+y的值别人就查表求和就行。而你却是在for这么多次,永远不会比它快。我认为这不是代码效率的问题。是别人花了大量的初始工作,有更好的算法,而你的算法也许永远也不可能有别人快。不要在这浪费时间比较了,这不是代码问题。
      

  15.   

    你这样算当然比不过MATLAB,人家用的肯定是优化算法。
    矩阵相乘有特别的快速算法,你可以查查斯特拉森方法等。还有,在多重循环内部任何一点额外开销都会显著影响效率,你那么多的间接寻址在内循环也有很大的浪费。
    加OpenMP的#pragma omp 吧,如果你是多核的电脑。
      

  16.   

    矩阵乘法里有一种Strassen(斯特拉森)算法,算法复杂性要比通常的矩阵乘法低一些,这个算法在《算法导论里有介绍》,可以试一试。矩阵计算是matlab的强项,自己编程序很难超越它,我看可以用并行计算实现矩阵乘法
      

  17.   

    算法问题,要是谁都能编出超越matlab矩阵运算的程序,matlab就卖不出去啦