行列および配列のコード生成
MATLAB® は、行列データおよび配列 (1 次元、2 次元、...) を列優先の形式でベクトルとして格納します。Simulink® およびコード ジェネレーターは、配列データを列優先または行優先の形式で格納できます。列優先のレイアウトで格納される配列の場合、列の要素はメモリ内で連続しています。行優先のレイアウトでは、行の要素が連続しています。配列レイアウトは、順番、形式、表現とも呼ばれます。要素を格納する順番は、統合、有用性、およびパフォーマンスにとって重要であることがあります。特定の順番で格納されたデータ上でパフォーマンスが向上するアルゴリズムもあります。
プログラミング言語および環境は、すべてのデータに対して単一の配列レイアウトを想定します。MATLAB と Fortran は、既定で列優先のレイアウトを使用しますが、C と C++ は行優先のレイアウトを使用します。Simulink Coder™ では、行優先のレイアウトまたは列優先のレイアウトを使用する C/C++ コードを生成できます。
コンピューター メモリへの配列の格納
コンピューター メモリは、データを 1 次元配列として格納します。たとえば、3 行 3 列の行列を宣言した場合、この行列はソフトウェアによって 9 つの要素をもつ 1 次元配列として格納されます。既定の設定では、MATLAB はこれらの要素を列優先の配列レイアウトで格納します。各列の要素はメモリ内で連続しています。
行列 A
を考えます。
A = 1 2 3 4 5 6 7 8 9
A
は、この順序で長さ 9 の配列に変換されます。 A(1) = A(1,1) = 1; A(2) = A(2,1) = 4; A(3) = A(3,1) = 7; A(4) = A(1,2) = 2; A(5) = A(2,2) = 5;
列優先の形式では、メモリ上の配列の次の要素にアクセスする場合は、その配列の最初のインデックスをインクリメントします。たとえば、次のそれぞれの要素の組はメモリにその順番で格納されます。
A(i)
およびA(i+1)
B(i,j)
およびB(i+1,j)
C(i,j,k)
およびC(i+1,j,k)
既定では、行列 A
は、メモリでは以下の配列で表現されます。
1 4 7 2 5 8 3 6 9
行優先の配列レイアウトでは、プログラミング言語は、行要素がメモリ内で連続するよう格納します。行優先のレイアウトでは、配列の要素は次のように格納されます。
1 2 3 4 5 6 7 8 9
N 次元配列は、列優先または行優先のレイアウトで格納できます。列優先のレイアウトでは、最初 (左端) の次元またはインデックスの要素がメモリ内で連続します。行優先のレイアウトでは、最後 (右端) の次元またはインデックスの要素が連続します。
MATLAB データの内部表現形式の詳細については、MATLAB データを参照してください。
コード生成ソフトウェアが既定で列優先の形式を採用しているのには、いくつかの理由があります。
信号および配列処理の世界では、MATLAB、LAPack、Fortran90、DSP ライブラリをはじめとして、列優先の配列レイアウトが広く採用されています。
列はフレームベースの処理におけるチャネルに相当します。このような場合には、列優先のストレージの方が効率が高くなります。
列優先の配列はその要素である部分行列に対しても自己矛盾がありません。
列優先の 2 次元配列は、1 次元配列の単純な連結です。
列優先の 3 次元配列は、2 次元配列の単純な連結です。
stride は同じ次元の次の要素のインデックスとなるメモリ位置の数になります。最初の次元の stride は 1 要素です。n 次元の要素の stride は、より低い次元のサイズの積になります。
行優先の n 次元配列では、最も高い次元の stride は常に 1 です。部分行列を操作する場合は、通常はメモリ上に分散したデータへのアクセスです。そのため、効率的なインデックス化には不向きです。
C では行優先の形式が使用されます。MATLAB および Simulink では既定で列優先の形式が使用されます。行優先の配列レイアウトを使用するコードを生成するよう、コード生成ソフトウェアを設定できます。外部 C コードを生成されたコードと統合している場合、この表に示される考慮事項を参照してください。
アクション | 考慮事項 |
---|---|
コード生成用のモデルの配列レイアウトの設定。 | [コンフィギュレーション パラメーター] ダイアログ ボックスで、モデル コンフィギュレーション パラメーター [配列のレイアウト] を [列優先] または [行優先] に設定します。 |
シミュレーションおよびコード生成に効率的な行優先アルゴリズムの有効化。 | モデル コンフィギュレーション パラメーター [行優先の配列レイアウトに最適化されたアルゴリズムを使用] をオンにします。 |
行優先の配列レイアウトの外部 C コード関数と生成されたコードの統合。 | 以下を使用して、外部コード関数を生成されたコードに統合する S-Function を作成します。
C Caller ブロックを使用して、外部 C 関数を Simulink で呼び出します。モデル コンフィギュレーション パラメーター [既定の関数配列のレイアウト] を使用して、カスタム C 関数の配列レイアウトを指定します。 MATLAB Function ブロック内で |
コード ジェネレーターの行列パラメーター
コンパイルされたモデル ファイル
は、MATLAB 構文の文字ベクトルとして行列を表し、暗黙的なストレージ形式はありません。この形式を使用すると、model
.rtw.rtw
ファイルの文字ベクトルをコピーして MATLAB ファイルに貼り付け、MATLAB に認識させることができます。
列優先のレイアウト
たとえば、Constant ブロックの 3 行 3 列の行列、
1 2 3 4 5 6 7 8 9
model
.rtw
に以下のように格納されます。Parameter { Identifier "Constant_Value" LogicalSrc P0 Protected no Value [1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0] CGTypeIdx 18 ContainerCGTypeIdx 19 ReferencedBy Matrix(1,4) [[0, -1, 0, 0];] GraphicalRef Matrix(1,2) [[0, 1];] BHMPrmIdx 0 GraphicalSource [0, 1] OwnerSysIdx [0, -1] VarGroupIdx [1, 0] WasAccessedAsVariable 1 }
ファイルは行列パラメーターの実際の格納を宣言します。形式が列優先レイアウトであることがわかります。model
_data.c
Parameters model_P = { /* Expression: [ [1,2,3] ; [4,5,6] ;[7,8,9]] * Referenced by: '<Root>/Constant ' */ { 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 } };
行優先のレイアウト
たとえば、Constant ブロックの 3 行 3 列の行列、
1 2 3 4 5 6 7 8 9
model
.rtw
に以下のように格納されます。Parameter { Identifier "Constant_Value" LogicalSrc P0 Protected no Value [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] CGTypeIdx 18 ContainerCGTypeIdx 19 ReferencedBy Matrix(1,4) [[0, -1, 0, 0];] GraphicalRef Matrix(1,2) [[0, 1];] BHMPrmIdx 0 GraphicalSource [0, 1] OwnerSysIdx [0, -1] VarGroupIdx [1, 0] WasAccessedAsVariable 1 }
ファイルは行列パラメーターの実際の格納を宣言します。形式が行優先のレイアウトであることがわかります。model
_data.h
Parameters model_P = { /* Expression: [ [1,2,3] ; [4,5,6] ;[7,8,9]] * Referenced by: '<Root>/Constant ' */ { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 } };
複素数配列の内部データ ストレージ
Simulink およびコード ジェネレーターの内部データ ストレージ形式と MATLAB の内部データ ストレージ形式では、複素数配列のストレージのみが異なります。MATLAB では、実数部と虚数部は個別の配列に格納されます。Simulink とコード ジェネレーターでは、実数部と虚数部はインターリーブされた形式で格納されます。メモリ中の数字は実数、虚数、実数、虚数というように交互に格納されます。この表現形式を使用することにより、Simulink ライン上の小信号や Mux ブロックおよびその他のバーチャルな信号操作ブロックについても効率的な実装が可能になります。たとえば、信号では入力を実際にコピーせず、単に参照します。
行優先のコード生成でサポートされていないブロック
コード ジェネレーターは、行優先の配列レイアウトでのコード生成で以下のブロックをサポートしません。
Continuous
Derivative
Integrator
Integrator Limited
Integrator, Second-Order
Integrator, Second-Order Limited
PID Controller
PID Controller (2DOF)
State-Space
Transfer Fcn
Transport Delay
Variable Time Delay
Variable Transport Delay
Zero-Pole
string 操作ブロック
ASCII to String
Compose String
Scan String
String Compare
String Concatenate
String Constant
String Contains
String Count
String Find
String Length
String to ASCII
String to Double
String to Enum
String to Single
Substring
To String
User-Defined Functions
Interpreted MATLAB Function
Level-2 MATLAB S-Function
Sources
From Spreadsheet
Signal Attributes
IC
行優先のコード生成の制限
可変サイズ信号は行優先のコード生成でサポートされていません。