このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
coder.inline
生成されたコードで現在の関数のインライン化を制御する
説明
coder.inline("always")
は、生成されたコードで現在の関数 (coder.inline
がある関数) をインライン化します。coder.inline("always")
最適化命令を使用して、関数呼び出しを呼び出される関数の本文に置き換えます。インライン化により、関数呼び出しのオーバーヘッドがなくなり、生成された C/C++ コードをさらに最適化できます。ただし、インライン化で生成される C/C++ コードは大きく、複雑になることがあります。
coder.inline("always")
命令では以下のインライン化はサポートされていません。
エントリポイント関数
再帰関数
parfor
ループを含む関数parfor
ループから呼び出される関数
coder.inline("never")
は、生成コードで使用されている関数がインライン化されるのを防ぎます。coder.inline("never")
最適化命令は、MATLAB® ソース コードと生成コードの間のマッピングを単純化する場合に使用します。
coder.inline("never")
命令では以下のインライン化は阻止されません。
空の関数
定数出力を返す関数
上記の状況でもインライン化を阻止するには、MATLAB コードの関数呼び出しサイトの入力で関数 coder.ignoreConst
を使用します。詳細については、Resolve Issue: coder.inline("never") and coder.nonInlineCall Do Not Prevent Function Inliningを参照してください。
coder.inline("default")
は、コード ジェネレーターに対して、内部のヒューリスティックな方法を使用して現在の関数をインライン化するかどうかを指示します。通常は、そうしたヒューリスティックな方法によって高度に最適化されたコードが生成されます。
例
関数のインライン化の制御
2 つのローカル関数 local_Inline
と local_NoInline
を呼び出すエントリポイント関数 inliningEntryPoint
を作成します。どちらのローカル関数も入力値の 2 乗を返します。ただし、local_Inline
は命令 coder.inline("always")
を使用しますが、local_NoInline
は命令 coder.inline("never")
を使用します。
type inliningEntryPoint.m
function [x,y] = inliningEntryPoint(n) %#codegen arguments n (1,1) double end x = local_Inline(n); y = local_NoInline(n); end function y = local_Inline(x) coder.inline("always"); y = x^2; end function y = local_NoInline(x) coder.inline("never"); y = x^2; end
inliningEntryPoint
の C コードを生成し、生成コード内のエントリポイント関数を検査します。コード ジェネレーターは、local_Inline
の呼び出しをインライン化しますが、local_NoInline
の呼び出しはインライン化しません。
codegen -config:lib inliningEntryPoint
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/inliningEntryPoint/html/report.mldatx')
type(fullfile("codegen","lib","inliningEntryPoint","inliningEntryPoint.c"))
/* * File: inliningEntryPoint.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:06:37 */ /* Include Files */ #include "inliningEntryPoint.h" /* Function Declarations */ static double local_NoInline(double x); /* Function Definitions */ /* * Arguments : double x * Return Type : double */ static double local_NoInline(double x) { return x * x; } /* * Arguments : double n * double *x * double *y * Return Type : void */ void inliningEntryPoint(double n, double *x, double *y) { *x = n * n; *y = local_NoInline(n); } /* * File trailer for inliningEntryPoint.c * * [EOF] */
フロー制御ステートメントでの coder.inline
の使用
複数の coder.inline
命令を使用して、入力引数などのパラメーターに基づいて関数のインライン化を制御できます。
ローカル関数 simpleDivision
を呼び出すエントリポイント関数 conditionalInlining
を作成します。複数の coder.inline
命令を使用して、両方の入力引数がスカラーの場合にのみ simpleDivision
をインライン化するようにコード ジェネレーターに指示します。
type conditionalInlining.m
function out = conditionalInlining(x,y) %#codegen out = simpleDivision(x,y); end function y = simpleDivision(dividend, divisor) if isscalar(dividend) && isscalar(divisor) forceInlining = "always"; else forceInlining = "default"; end coder.inline(forceInlining) y = dividend / divisor; end
スカラー入力を指定して conditionalInlining
の C コードを生成し、生成されたコード内のエントリポイント関数を調べます。コード ジェネレーターは、生成されたコードで simpleDivision
をインライン化します。
codegen -config:lib conditionalInlining -args {3 4}
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/conditionalInlining/html/report.mldatx')
type(fullfile("codegen","lib","conditionalInlining","conditionalInlining.c"))
/* * File: conditionalInlining.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:07:41 */ /* Include Files */ #include "conditionalInlining.h" /* Function Definitions */ /* * Arguments : double x * double y * Return Type : double */ double conditionalInlining(double x, double y) { return x / y; } /* * File trailer for conditionalInlining.c * * [EOF] */
ベクトル入力を指定して conditionalInlining
の C コードを生成し、生成されたコード内のエントリポイント関数を調べます。コード ジェネレーターは内部のヒューリスティックな方法を使用して、生成されたコード内で simpleDivision
をインライン化するかどうかを決定します。
codegen -config:lib conditionalInlining -args {1:10 11:20}
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/conditionalInlining/html/report.mldatx')
type(fullfile("codegen","lib","conditionalInlining","conditionalInlining.c"))
/* * File: conditionalInlining.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:07:45 */ /* Include Files */ #include "conditionalInlining.h" #include "rt_nonfinite.h" #include "xnrm2.h" #include "rt_nonfinite.h" #include <emmintrin.h> #include <math.h> #include <string.h> /* Function Declarations */ static double rt_hypotd_snf(double u0, double u1); /* Function Definitions */ /* * Arguments : double u0 * double u1 * Return Type : double */ static double rt_hypotd_snf(double u0, double u1) { double a; double b; double y; a = fabs(u0); b = fabs(u1); if (a < b) { a /= b; y = b * sqrt(a * a + 1.0); } else if (a > b) { b /= a; y = a * sqrt(b * b + 1.0); } else if (rtIsNaN(b)) { y = rtNaN; } else { y = a * 1.4142135623730951; } return y; } /* * Arguments : const double x[10] * const double y[10] * Return Type : double */ double conditionalInlining(const double x[10], const double y[10]) { __m128d r; __m128d r1; double A[10]; double B[10]; double out; double tau; double wj; int i; int knt; int rankA; memcpy(&A[0], &y[0], 10U * sizeof(double)); memcpy(&B[0], &x[0], 10U * sizeof(double)); tau = 0.0; for (i = 0; i < 1; i++) { double atmp; atmp = A[0]; tau = 0.0; wj = xnrm2(A); if (wj != 0.0) { double beta1; beta1 = rt_hypotd_snf(A[0], wj); if (A[0] >= 0.0) { beta1 = -beta1; } if (fabs(beta1) < 1.0020841800044864E-292) { knt = 0; do { knt++; r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(9.9792015476736E+291); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= 9.9792015476736E+291; beta1 *= 9.9792015476736E+291; atmp *= 9.9792015476736E+291; } while ((fabs(beta1) < 1.0020841800044864E-292) && (knt < 20)); beta1 = rt_hypotd_snf(atmp, xnrm2(A)); if (atmp >= 0.0) { beta1 = -beta1; } tau = (beta1 - atmp) / beta1; wj = 1.0 / (atmp - beta1); r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(wj); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= wj; for (rankA = 0; rankA < knt; rankA++) { beta1 *= 1.0020841800044864E-292; } atmp = beta1; } else { tau = (beta1 - A[0]) / beta1; wj = 1.0 / (A[0] - beta1); r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(wj); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= wj; atmp = beta1; } } A[0] = atmp; } rankA = 0; wj = fabs(A[0]); if (!(wj <= 2.2204460492503131E-14 * wj)) { rankA = 1; } out = 0.0; if (tau != 0.0) { wj = x[0]; for (i = 0; i < 9; i++) { wj += A[i + 1] * x[i + 1]; } wj *= tau; if (wj != 0.0) { __m128d r2; B[0] = x[0] - wj; r = _mm_loadu_pd(&A[1]); r1 = _mm_loadu_pd(&B[1]); r2 = _mm_set1_pd(wj); _mm_storeu_pd(&B[1], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[3]); r1 = _mm_loadu_pd(&B[3]); _mm_storeu_pd(&B[3], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[5]); r1 = _mm_loadu_pd(&B[5]); _mm_storeu_pd(&B[5], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[7]); r1 = _mm_loadu_pd(&B[7]); _mm_storeu_pd(&B[7], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); } } for (i = 0; i < rankA; i++) { out = B[0]; } for (knt = rankA; knt >= 1; knt--) { out /= A[0]; } return out; } /* * File trailer for conditionalInlining.c * * [EOF] */
ヒント
codegen
コマンドまたはfiaccel
(Fixed-Point Designer) コマンドを使用する場合に、-O disable:inline
オプションを使用することで、すべての関数のインライン化を無効にできます。作成した関数から生成された C/C++ コードと、MathWorks® 関数から生成された C/C++ コードでは、速度と読みやすさの要件が異なる場合があります。追加のグローバル設定を使用すると、生成されたコード ベースのこれらの 2 つの部分のインライン化を制御できます。生成コードのパフォーマンスと可読性を微調整するためのインライン化の制御を参照してください。
拡張機能
C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。
GPU コード生成
GPU Coder™ を使用して NVIDIA® GPU のための CUDA® コードを生成します。
HDL コード生成
HDL Coder™ を使用して FPGA 設計および ASIC 設計のための VHDL、Verilog および SystemVerilog のコードを生成します。
関数 coder.inline
では、MATLAB から高位合成へのコード生成がサポートされています。
バージョン履歴
R2011a で導入
MATLAB コマンド
次の MATLAB コマンドに対応するリンクがクリックされました。
コマンドを MATLAB コマンド ウィンドウに入力して実行してください。Web ブラウザーは MATLAB コマンドをサポートしていません。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)