Flying Fish

Friday, April 08, 2005

Matlab 的内存管理

用 Matlab 进行大规模科学计算或仿真时,内存是一个需要时常注意的问题。当你写的 Matlab 程序跳出“Out of Memory” 时,以下几点措施是需要优先考虑的解决方法:

1. 确保内存的连续性

Matlab 中数组必须占用连续分配的内存段,当无法为新建的数组分配连续的内存段的时候,"Out of Memory" 就会出现。由于反复分配和释放数组会使可用的连续内存段减少,因此当 Matlab 刚刚启动时其连续内存最多,此时往往可以新建非常大的数组,这一点可以用命令 feature('memstats')(在 7.0 版本以上)看出。如果现实的最大连续内存段很小,但实际可用内存(非连续的)仍旧很多,则表明内存中碎片太多了。此时可以考虑用 pack 命令,pack 命令的作用就是将所有内存中的数组写入硬盘,然后重新建立这些数组,以减少内存碎片。此外,在命令行或者程序中都可以使用 clear 命令,随时减少不必要的内存。

2. 3GB 开关

由于32位 Windows 操作系统的限制,每个进程只能使用最多 2GB 的虚拟内存地址空间,因此 Matlab 的可分配内存也受到相应的限制。Matlab 7.0.1 引进了新的内存管理机制,可以利用 Windows 的 3GB 开关,使用 3GB 开关启动的 Windows 每个进程可以在多分配 1 GB 的虚拟地址空间,具体的操作方法可见:http://www.mathworks.com/support/tech-notes/1100/1106.html

3. 减少使用双浮点数

Matlab 默认的数字类型是双精度浮点数 (double),每个双浮点数占用 8 个字节。对于一些整数操作来说,使用双浮点数显得很浪费。在 Matlab 中可以在预先分配数组时指定使用的数字类型如以下命令:zero(10, 10, 'uint8') 。对于浮点数,在很多精度要求不高的情况下,可以使用4个字节的单浮点数 (single),可以减少一半的内存。关于单、双浮点数的精度对照如下,以便根据需要选择使用:

single: 精度 (1.1921e-007) 最大数 (3.4028e+038)
double: 精度 (2.2204e-016) 最大数 (1.7977e+308)

Thursday, February 17, 2005

Matlab 的 C 语言接口

Matlab 提供了 C 语言的外部接口,对于一些处于速度瓶颈的函数,用户可以选择用 C 语言来编译实现,可以大大降低运算时间。

根据 Matlab 的文档,用 C 语言来实现的函数需要有统一的函数入口:

void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])

用户可以修改此函数来实现 Matlab 和 C 代码的输入输出转换,还可以调用其他 C 函数来实现运算。如此编写 C 程序一个缺点是 C 语言的功能有限,比如不能使用面向对象的编程结构,变量必须在函数最前端申明等等,如果能用 C++ 编程则会更加方便。但是整个 Matlab 网站上的文档都只讨论的 C 语言的情况,只字不提 C++ 。

原来 Matlab 自带的 LCC C 编译器只提供对 C 语言的支持,但是你可以选择机器上安装的其他 C++ 编译器来完成编译任务,比如 Visual Studio .Net 2003,用 "mex -setup" 可以选择使用不同的编译器。当使用支持 C++ 的编译器后,可以把代码后缀名改成 .cpp ,然后就可以用 C++ 编写代码了,入口函数仍然是 mexFunction(...),这个相当于一般 C++ 程序中的 main(...) 函数,其他的就和写别的 C++ 程序一模一样,可以用 class 定义,template,用 STL 等等。

如果你的机器上没有安装 Visual Studio,现在微软免费提供的全套的命令行的 VC 编译工具,可以在这里找到:
http://msdn.microsoft.com/visualc/vctoolkit2003/
再配上一个免费的文本编辑工具就可以了。

Wednesday, February 09, 2005

Matlab 稀疏矩阵操作

Matlab 有很好的稀疏矩阵 (sparse matrix) 支持,稀疏矩阵可以同完全矩阵在任何运算中同时出现。稀疏矩阵的用处不用多说,很多雅克比矩阵需要用它来表示,否则内存完全不可能装得下。但是稀疏矩阵的使用同 Matlab 的其他功能一样,也有一些窍门,不同的代码可能会有完全不同的运行时间差别。

  1. 用 spalloc 预留空间

    同完全矩阵一样,稀疏矩阵也可以预先分配空间,以加快随后的访问速度。

  2. 用 cell2mat 分段创建大的稀疏矩阵

    在给大的稀疏矩阵赋值时,你会发现越到后面赋值得速度越慢,原因是稀疏矩阵的数据结构变得越来越复杂了,需要很长的访问时间。在这种情况下,可以将整个矩阵分块构建,分别存在 cell 数组,最后用 cell2mat 命令把这些矩阵合并成一个矩阵,这样的操作可以大大减少运算时间。

  3. 访问超大型数组

    Matlab 可以构建行列唯数非常大的稀疏矩阵,但是在这时候需要注意,如果单单用一唯数来索引矩阵中的元素的话,如 M(ai) 而不是 M(i, j),ai = i + (j-1) * i_dim 有可能超过 32 位整数所能表示的范围, Matlab 会提示出错信息,此时必须使用二唯索引。



Navigation: Go to [My Homepage] [My Research Blog] [My Courses Blog]

Thursday, January 27, 2005

解释执行的 Matlab

Matlab 的代码是解释执行的,运行函数或脚本时不需要编译,这样可以减少从编程到运行的时间,但是这样也使得它无法实现通常程序编译时的变量类型检查,这样的做法既有好处也有坏处。

好处是,matlab 中编写函数的相当方便,变量不需要申明,没有类型检查,函数的调用也没有规定输入参数必须匹配。对于一些经常在改动的函数,我通常把它们的参数归成几类,分别存在不同的结构(structure) 里,这样如果要增加或减少一些参数只需要在函数调用前改动这些结构里的域(field),而不需要修改函数入口的参数定义,节省了修改代码的时间。

但是这样一来也有不少问题,没有变量类型检查后,好多错误(类型不匹配,变量未定义便引用)只有在运行时才会出现,因此有些新写的程序要试着运行好多次之后才通过,对于一些运行时间较长的程序,这种调试方法非常不方便,必须要在写程序时要加倍小心,但是错误还是在所难免 :(

最后说一个调试 matlab 的小技巧,用这段代码:

try
... code to be debugged ...
catch
keyboard;
end

这样在程序执行出错的时候会自动转到键盘命令行调试,你就可以输入命令来查看各种当时的变量了。


Navigation: Go to [My Homepage] [My Research Blog] [My Courses Blog]

Friday, November 19, 2004

长时间运行 Matlab 的工具

实验室的机器晚上都是开着没用的,于是我就把一些需要长时间运行的程序放到晚上运行。但是问题是有的程序一个晚上还运行不完,第二天早上来了就会比较麻烦,如果把程序关了吧,那么整个晚上运行的结果就全没了,但是如果不关的话,那么就要忍受着所有的系统资源都被背景程序占用的痛苦,没法顺畅地使用电脑了。以前虽然可以通过任务管理器降低程序进程 (Process) 的优先级来让前景程序获得足够的cpu时间,但是有些程序会不时弹出一些窗口,让你的桌面不得安宁。

最近终于通过不懈的搜索,找到了这个工具 Process Explorer: http://www.sysinternals.com/ntw2k/freeware/procexp.shtml 。它具有任务管理器的所有功能,而且可以显示进程的各种信息,最有用的工具便是进程暂停 (suspend),对于你想暂停运行的进程,只要右击选择 suspend,该进程便不会运行,也不会继续占用 CPU 资源(当然,内存是继续占用的),右击选择 resume 则可以继续运行暂停了的程序。通过 Process Explorer,我就可以每天早上把没有运行完的程序暂停,等到晚上下班时再打开继续运行,充分利用计算资源。

其实最理想的进程管理是可以把每个进程写入硬盘,这样就可以完全不占用系统任何资源了,下次需要继续运行的时候再调入内存,不过目前为止似乎还没有工具支持这种操作。


Navigation: Go to [My Homepage] [My Research Blog] [My Courses Blog]

Sunday, November 07, 2004

Matlab Central File Exchange (文件交换中心) 和 RSS

整个10月都没有写blogger,主要是忙着赶paper的deadline,现在终于忙完了,当然啦,有时候感觉没有什么可以写的也是一个问题 :)

我最近尝试了去 Matlab Central File Exchange 网站访问了几次,包括下载了几个有用的程序和上载了一个我最近自己写的 matlab 函数 (关于三角化一组分布在单位圆上的离散点的函数)link。总体觉得mathworks开设这个网站还是蛮不错的,仔细找找说不定可以找到一些现在的算法实现,而且用户可以对每个上载的程序打分,写评语,以便其他用户有所借鉴。

Central File Exchange 另一个比较方便的是提供了一个 RSS news feed,你可以直接用 RSS 阅读器下载最新的更新情况,而且如果配合RSS Reader中的过滤功能,就可以只看到你所想要看到的内容了。由于RSS Reader 可以设置成自动定时更新,因此这种阅读方式将更加有效,不过,前提是定义一个好的过滤器。:)


Navigation: Go to [My Homepage] [My Research Blog] [My Courses Blog]

Tuesday, September 21, 2004

Matlab Profile 和 MLint

Matlab 的最新版本 7.0 增加和改进了许多辅助编程的功能,非常有利于提高工作效率。其中比较有用的两项就是 Matlab Profiling 和 MLint 。

Profiling (翻作运行时间记录?) 是用来记录程序各部分的运行时间,从而找到优化程序的着手点的。新版的 Profiling 运行相当简单,用 'Profile on' 和 'Profile off' 来打开和关闭,而 profview(function_name) 则会显示该函数的运行时间分布情况,matlab 会把该函数的运行时间,他所调用的函数的运行时间,以及函数中占用时间较长的语句分别列出,使整个程序的运行时间分布一目了然,也使得优化和改进程序有确切的目标。

MLint 应该是 Matlab 新增添的组件,它可以检查所写的 M 文件的格式和语法情况,提供一些改进的建议,对于刚刚写完的 matlab 函数,这是一个非常好的检查错误的机会, :)


Navigation: Go to [My Homepage] [My Research Blog] [My Courses Blog]