Matlabで大量のデータを扱い数値計算をするには高速化あるいはメモリ確保の必要が出てきますが、以下はそれに関して私が設定等で面倒だった点をまとめた覚書です。
T.Matlabコンパイラ関連
A.Unix (Matlab 6.5 R13 + Matlab compiler ver 3.0 + Sun ONE Studio 8)
B.Windows XP(Matlab 6.5.1 R13 + Matlab compiler ver 3.0 + Visual C/C++
6.0 or Borland C++ compiler 5.5) C.Windows XP(Matlab 7.0.4 R14 + Matlab
compiler ver 4.2 + Visual C/C++ 6.0 or Borland C++ compiler 5.5)
以上の3環境での話です。
Unix, Windows環境ともにmファイルをC/C++のソースファイルに変換してコンパイルし、スタンドアローンのC/C++の実行ファイルを作る。これにより、matlabなしでプログラムを動かしたり、計算速度を高速化できることがある。コンパイルによって高速化できるかはプログラムによる。
# 最近のmatlab compilerは高速化を意図してつくられていない。ただし、大容量のデータを扱うときのメモリ確保に関してはCommand
windowよりいい場合がある。
必要なのはMatlab + Matlabコンパイラ +ANSI C / C++ コンパイラ 。ただし、プラットフォームによって必要なCコンパイラが違うので確認が必要である。
Gnu C (gcc) はなんとMatlab compiler Unix版ではサポートされていないので注意する。システムnativeのANSI
C/C++コンパイラが必要となる。Sunのコンパイラでサポートが確認されているのはWorkshop
Compiler 6.0 on Solarisまでだが、Sun ONE Studio 8でも一応動いている。。
一方Windows版MatlabではCコンパイラlccがバンドルされている。
1.コンパイラ設定ファイル
mcc, mbuild, mexがコンパイラ関連のコマンドだが、使う前に以下の設定をする。
A.Unix
matlabコマンドラインの
mex -setup
でできる各自のHOME/.matlab/R13/mexopts.shのWorkShop関連の記述でccの位置をフルパスで指定する。
#WorkShop Compilers 5.0 98/12/15 C 5.0
CC='/opt/SUNWspro/bin/cc'
次に
mbuild -setup
でできる設定ファイル、HOME/.matlab/R13/mbuildopts.shの中のSUN Compiler関連の記述でccの位置をフルパスで同様に以下のように設定する。
#WorkShop Compilers 5.0 98/12/15 C 5.0
CC='/opt/SUNWspro/bin/cc'
さらにmbuildopts.shライブラリのパスの設定で、SUN Compilerのライブラリのパスを加える。
MLIBS="-L$TMW_ROOT/extern/lib/$Arch -L$TMW_ROOT/bin/$Arch
-L/opt/SUNWspro/prod/lib $OTHER_LIBS"
Unixでスタンドアローン実行ファイルを走らせるためにはシェルの環境変数に上記のライブラリのパスを加える必要がある。
たとえば.kshrcに、
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/matlab6p5/extern/lib/sol2
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/matlab6p5/bin/sol2
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SUNWspro/prod/lib
を加える。
Windows
B.Windows XP(Matlab 6.5.1 R13 + Matlab compiler ver 3.0 + Visual C/C++ 6.0 or Borland C++ compiler 5.5)
C.Windows XP(Matlab 7.0.4 R14 + Matlab compiler ver 4.2 + Visual C/C++
6.0 or Borland C++ compiler 5.5)
両環境ともUnixと同様にmatlabコマンドラインで
mex -setup
mbuild -setup
で、C/C++コンパイラを指定する。私はVisual C/C++またはBorland C++(これはフリー)を使用している。
C:\Documents and Settings\username\Application Data\MathWorks\MATLAB\R13\compopts.bat
C:\Documents and Settings\username\Application Data\MathWorks\MATLAB\R13\mexopts.bat
がその結果できる設定batファイル。
B.Matlab 6.5.1 R13 + Matlab compiler ver 3.0の場合
Mglinstaller.exeを実行してスタンドアロン環境の作業フォルダに必要なdllをコピーする。
このフォルダ\workspaceの下の"c:\..\workspace\bin\win32"にdllファイルはコピーされる。
このフォルダパス"c:\..\workspace\bin\win32"をコントロールパネル->詳細設定->環境変数のシステム環境変数PATHに付け加える。ただし、matlab自体のパス"MATLAB6P5\bin\win32"よりも前に来るように編集する。
C.Matlab 7.0.4 R14 + Matlab compiler ver 4.2 の場合
コンパイルした.exeファイルと.ctfファイルとMCRinstaller.exeが必要。
スタンドアロンで走らせたい環境にこれらのファイルをコピーする。
MGRinstaller.exeを実行してMATLAB Component Runtime (MCR)をインストールする。
2.ファンクションM-ファイルと スクリプトM-ファイル
M-ファイルは機能によってファンクションM-ファイルとスクリプトMファイルに分けることができる。
スクリプトM-ファイル
一連のコマンド・関数をまとめて処理することができる。
実行したいステートメントを順に記述するだけ。
ファイル内で処理された変数は、Workspace変数として定義、共有される。
MATLABインタプリタのコマンドラインからこの変数にアクセスできる。
ファンクションM-ファイル
入力引数と出力引数を伴う、ユーザ定義の関数。
入出力の関係を記述したfunction で始まる関数宣言の行が必要。
ファイル内で処理された変数は、このファイル用のWorkspace変数として定義。
ファンクションM-ファイル内で利用される変数は、その関数に限られる。
MATLABインタプリタのコマンドラインからこの変数にアクセスすることはできない。
スクリプトM-ファイルはMATLAB compilerではコンパイルできない!!
ファンクションM-ファイルに変換する必要がある。
スクリプトをファンクションに変換するためには、M-ファイルの一番最初に function
行を追加する。
function [出力引数]= scriptfilename(入力引数)
入出力引数がなければ空でいい。コンパイルするためにはとにかくfunction行が必要。
はじめにスクリプトM-ファイルでプログラムを作成する。アルゴリズムの検証等が終わったらそのプログラムをファンクションM-ファイルにする。こうするとデバッグ効率を含めたトータルの作業効率が良くなる。
3.コンパイル方法
mcc -m -v filename
でCスタンドアローン実行ファイルを生成する。
また
mcc -x -v filename
でmexファイル化される。
4.コンパイル上の注意
Load Save 等の入出力関数、EVAL関数はmファイルで動いていても、コンパイルするとうまくいかない場合がある。
ERROR: Error: Missing operator, comma, or semicolon.
というエラーメッセージがでる。
Loadのかわりに、fscanfで読み込み、Saveのかわりにfprintfで書き出すとうまく行く。他にもサポートされていない関数があるのでチェックが必要。
ただし、load, saveに比べて、fscanf, fprintfは時間がかかる。大容量データの場合はコンパイルによる高速化とトレードオフがあるかもしれない。
5.コンパイラの最適化設定
UnixであればCコンパイラの最適化オプションをMatlabコンパイラの設定ファイルmbuildopts.shを編集していろいろ試す。
例えば、Sunコンパイラだと -xO3よりも-xO4,-xO5が速い可能性がある。
また、Windowsでもcompopts.batの最適化オプションを試行錯誤する。Pentium 4マシンなら
Visual C/C++だと、 -Ox (速度最適化) -G5 (Pentiumコード用最適化)
Borland C++だと -Ox (速度最適化) -5 (Pentiumコード用最適化)
また、CよりもC++の方が若干速いこともある。
mcc -p -v filename
でC++スタンドアローンアプリケーションになる。
II.高速化のコツ
1.MATLAB の高速化の基本は、組み込み関数や行列ベクトル演算を駆使してfor
文をできるだけ使わないということ。
アルゴリズムで計算速度は全然違う。
2.また大きな行列を扱う場合、メモリのFragmentation(分断化)が問題になる場合がある。特にサイズを決めていない行列をループでデータを少しずつ加えて大きくしていく場合にこの問題がおきやすい。できれば最初に大きなzero行列などでメモリ領域を確保してしまって重ねがきしたがメモリー関連のエラーはでにくい。
3.1.2は必ずしも絶対的なルールではない。特に大きな行列を扱う場合は部分行列を操作するようなループ化したアルゴリズムを使わないとfragmentationがおきてメモリ関連のエラー(Out
of memory)がでることがある。
III.その他(蛇足)
1.実行時間の計測
tic toc
tic は、ストップウォッチタイマを開始する。toc は、 tic が使われてからの経過時間。
tic;
...
endt=toc
あるいはcputimeを使う。cputimeはmatlabが起動してからのcpu時間(秒)。
startt = cputime;
...
endt = cputime-t
おまけ Unix and Linux tips
その他
Vi
1.置換
コマンドモードで
:%s/aaa/bbb/g 文字列aaaをbbbに置換する。
:%s/aaa/bbb/gc interactiveに置換。
Unix & linux
useful command
wc 行数 単語数 サイズ を表示