Main Content

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

行列および配列のコード生成

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 を作成します。

  • SimStruct 関数 ssSetArrayLayoutForCodeGen

  • S-Function Builder ブロックの [配列レイアウト] 設定。

  • legacy_code のレガシ コード ツール オプション convert2DMatrixToRowMajorconvert2DMatrixToRowMajor の使用はコード効率に影響します。

C Caller ブロックを使用して、外部 C 関数を Simulink で呼び出します。モデル コンフィギュレーション パラメーター [既定の関数配列のレイアウト] を使用して、カスタム C 関数の配列レイアウトを指定します。

MATLAB Function ブロック内で coder.ceval を使用することもできます。MATLAB Function ブロック内の行優先のデータとのインターフェイスを参照してください。

コード ジェネレーターの行列パラメーター

コンパイルされたモデル ファイル model.rtw は、MATLAB 構文の文字ベクトルとして行列を表し、暗黙的なストレージ形式はありません。この形式を使用すると、.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

User-Defined Functions

  • Interpreted MATLAB Function

  • Level-2 MATLAB S-Function

  • MATLAB System

Sources

  • From Spreadsheet

行優先のコード生成の制限

  • 可変サイズ信号は行優先のコード生成でサポートされていません。

関連するトピック