萍聚社区-德国热线-德国实用信息网

 找回密码
 注册

微信登录

微信扫一扫,快速登录

萍聚头条

查看: 1586|回复: 2

[电子] Matlab 和 C++ (2)

[复制链接]
发表于 2007-6-3 22:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册 微信登录

x
Matlab中用到c和汇编的一个例子:

老板让在非线性拟和时要计算一个评价函数:N= sum( diag( B'*B ) ) ; B= (A*S) .* log( (A*S) ./ X ) - A*S + X ; 因为A是一个很大的矩阵(1024*1024),所以,这个评价函数计算很慢。最慢的一步还是log。所以,把整个评价函数用c重新写了。
其中的log用的是汇编,发现还比较有用,就单独做了一个myLOG.m以代替matlab的log(计算自然对数ln值)
检验:
>> a=rand(1000,1000,10)*10;
>> tic;b=log(a);toc
Elapsed time is 2.521904 seconds.
>> tic;mylog(a);toc                 (为了节约内存,我们直接将输入的矩阵作为输出)
Elapsed time is 1.531487 seconds.
>> sqrt(sum(sum(sum((a-b).^2)))/1000/1000/10)          (误差)

ans =

  1.2344e-016

误差的来源主要是当计算的数值比较小的时候(1e-3),我们的汇编计算没有将计算值先修正为2附近的值。但是如果计算的值不是十分小,精度还是很好的。
主要的进步还是减少了时间。

不过,matlab在单步运算上还是比较优化的。假如不是汇编计算,用真的c算log,速度和matlab差不多。(文件中间定义了#define myln_sf(__a)   log(__a),可以用来比较c的log运算)。
另外,这个汇编在计算时,没有对数据检验,所以,如果用了负数,计算的速度慢不算,结果还不对,所以用的时候要注意。

用同样的方法还可以优化exp() sin() cos(),这些函数都很有用。尤其在计算fft的时候。
以后会贴一个完整的myfft,为的是独立于matlab。


//-----------------------------myLOG.m-------------------------------------------
#include <stdio.h>
//#include <time.h>
//#include <sys\timeb.h>
#include "mex.h"
#include "math.h"

//---------------------------------------------------------------------------
static long double dM_LOG2E = 1.4426950408889634073599246810019;
static long double dM_LN2 = 0.69314718055994530941723212145818;
static long double dONE      = 1;
//---------------------------------------------------------------------------
//#define myln_sf(__a)   log(__a)
#define MY_LCC
//---------------------------------------------------------------------------
#ifndef MY_LCC
/*--------------------------------------------------------------------------*/
double __declspec(naked) myln_sf(double __a){// asm for VC & BC
// 10M Rand data using 1.36 s, log(a) is 1.61 s
  asm{
  fld dM_LN2       //  using fldln2, it is 1.49 s !!!
  fld [esp+4]
  fyl2x
  ret
  };
}
#else
/*----------------------------------------------------------------------------------------------*/
double __declspec(naked) myln_sf(double __a){// asm for LCC
    _asm("fldl %dM_LN2");
    //_asm("fldln2");             // log(2), for speed, intel recommand using a real LN2 number instead of fldln2 which load internal LN2
    _asm("fldl 4(%esp)");       // a     : log(2)
    _asm("fyl2x");              // log(a)
    _asm("ret");
}
#endif
/*----------------------------------------------------------------------------------------------*/
#ifndef MY_LCC
void _export  mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
#else
void  mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
#endif
{
double *pdAddr;
int i,j;
const int *pnAddr;
if (1!=nrhs) mexErrMsgTxt("Using: myLog( aInOut );  Here, aInOut is both input and out put array, for speed up and less memory;");
if(mxDOUBLE_CLASS != mxGetClassID(prhs[0])) mexErrMsgTxt("Using: myLog( aInOut );  aInOut should be a double array;");
pnAddr  = mxGetDimensions(prhs[0]);
for(j=mxGetNumberOfDimensions(prhs[0])-(i=1); j>=0;j--)i*=pnAddr[j];
for(pdAddr = (double *)mxGetData (prhs[0]);i>0;i--, pdAddr++)*pdAddr = myln_sf(*pdAddr);
}
/*----------------------------------------------------------------------------------------------*/

注,以上默认的是还是LCC,如果是用VC 或者BC编译时请remark "#define MY_LCC"
因为masm和lcc的语法不同,这里给出了两个版本的汇编。
另外,打"//"的语句可以用于VC和BC。dM_LOG2E,dONE 虽然这里没有用到,但是在计算
exp sin cos时就有用了。因为用浮点处理器内部的这些数据速度会比用立即数慢。

评分

1

查看全部评分

Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2007-6-4 11:35 | 显示全部楼层
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2007-6-5 11:00 | 显示全部楼层
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

手机版|Archiver|AGB|Impressum|Datenschutzerklärung|萍聚社区-德国热线-德国实用信息网 |网站地图

GMT+2, 2024-5-8 03:32 , Processed in 0.055655 second(s), 20 queries , MemCached On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表