3.27 自動ベクトル化を制限または抑制する要因

以下の表に、ループの自動ベクトル化を制限または抑制する要因を示します。

表 3-5 自動ベクトル化を制限または抑制する要因

抑制要因 影響が及ぶ範囲
有効な NEON コンパイラライセンスがない
NEON 命令を生成するには、コンパイラバージョンによって異なる有効な NEON コンパイラライセンスが必要です。
RVCT 3.1 以降および ARM コンパイラ 4.1 には、有効な NEON コンパイラライセンスが必要です。
ARM コンパイラ 5.01 以降では、別の NEON コンパイラライセンスは必要ありません。
ソースコードにループがない 自動ベクトル化には、ループの分析が含まれます。ループがない場合、自動ベクトル化を適用することはできません。
ターゲットプロセッサ NEON 命令を生成するには、ターゲットプロセッサ(--cpu)が NEON の機能を備えている必要があります。このようなプロセッサには、Cortex-A7、Cortex-A8、Cortex-A9、Cortex-A12、Cortex-A15 などがあります。
浮動小数点コード 浮動小数点コードは常に自動的にベクトル化されるとは限りません。例えば、再関連付けが必要なループは、--fpmode fast を使用したコンパイル時にのみベクトル化されます。
デフォルトの --no_vectorize デフォルトでは、C または C++ コードからの NEON ベクタ命令の直接的な生成は無効になっているため、--vectorize を使用してこれを有効にする必要があります。
-Otime が指定されない 実行時間を短縮し、ループを有効にしてベクトル化を行うためには、-Otime を指定する必要があります。
-Onum の設定レベルが低い 設定する最適化レベルは、-O2 または -O3 である必要があります。-O0 または -O1 のレベルでは、ループはベクトル化されません。
不正な結果の可能性 不正な結果の可能性がある場合、その可能性がある箇所にはベクトル化は適用されません。自動ベクトル化に適するように、手作業でコードを調整する必要があります。
手作業による事前のコードの最適化の試み 手作業による事前のコードの最適化の試みは、自動ベクトル化を妨げる要因になります。たとえば、ソースコードの手作業によるループ展開や複雑な配列アクセスが該当します。
ベクタアクセスパターンがない ループの変数がベクタアクセスパターンを持たない場合、コンパイラは自動的にループをベクトル化できません。
ループの異なる繰り返しの間でのデータの依存関係 配列の使用や格納がループの異なる繰り返しのときにオーバーラップしている可能性がある場合は、データの依存関係の問題が存在します。オペレーションのベクタ順序によって結果が変化する可能性がある場合は、ループを安全にベクトル化することはできないため、コンパイラはループを元の形式のまま残すか、またはループの一部のみをベクトル化します。
メモリ階層 メインメモリから取得した大規模なデータセット上で比較的少ない算術演算を実行することは、システムのメモリ帯域幅によって制限されます。ほとんどのプロセッサでは、メモリの帯域幅とプロセッサの容量とのバランスが相対的に取れていません。これにより、自動ベクトル化処理に悪影響を及ぶことがあります。
ループの開始時点で繰り返し回数が固定されていない 自動ベクトル化のためには、一般的に、ループの開始時に繰り返し回数が固定される単純なループを記述することが最善です。ループの繰り返し回数が固定されていない場合は、アドレス指定は不可能です。
ループからの条件付き終了 ループからの条件付き終了を含まないループを記述することが最善です。
キャリーアラウンドスカラ変数 キャリーアラウンドスカラ変数は、ループの 1 つのパスで計算された値が次のパスに繰り越されるので自動ベクトル化にとって問題になります。
__promise(expr) が使用されていない 自動ベクトル化に違いをもたらすことができる場合に __promise(expr) を使用しないと、自動ベクトル化が制限されることがあります。
ポインタのエイリアス生成 ポインタのエイリアス生成は、自動的にベクトル化されたコードの使用を抑制します。
間接アドレス指定 NEON ユニットで処理できるのはメモリ内に連続して格納されるベクタだけなので、間接アドレス指定はベクトル化できません。
構造体の異なる部分へのアクセスが別個のループに分かれている 自動ベクトル化を行うには、構造体の各部分に対して同じループ内でアクセスする必要があります。
構造体の各メンバの長さが一貫していない 構造体の各メンバの長さがすべて同じでない場合、コンパイラはベクタロードを使用しません。
非インライン関数の呼び出し ループ内から非インライン関数を呼び出すと、ベクトル化できません。このような関数をベクトル化の対象にするには、 __inline キーワードか __forceinline キーワードでマークを付ける必要があります。
if ステートメントと switch ステートメント if ステートメントと switch ステートメントが大規模に使用されている場合、自動ベクトル化の効率に影響が及ぶ可能性があります。
--diag_warning=optimizations を使用すると、ベクトル化できた(またはできなかった)部分に関するコンパイラ診断を取得できます。
関連する概念
3.9 NEON ベクトル化によるパフォーマンスに影響を与える要因
3.12 コードをベクトル化するときのデータの依存関係による競合
3.17 条件付き終了の非ベクトル化
3.13 キャリーアラウンドスカラ変数とベクトル化
3.16 ポインタおよび間接アドレス指定を含むループの非ベクトル化
3.18 ベクトル化可能なループ繰り返し回数
3.19 __promise(expr) によるコンパイラへのループ繰り返し回数の指定
3.20 ベクトル化のための構造体アクセスのグループ化
3.21 ベクトル化と struct メンバの長さ
3.22 ループ内からの非インライン関数への関数呼び出しの非ベクトル化
3.23 条件付きステートメントと効率的なベクトル化
3.24 ベクトル化診断を使用してコードを調整し、パフォーマンスを改善する
関連する参考文書
8.192 --vectorize、--no_vectorize
3.7 ベクトル化可能なループ内のデータ参照
3.11 ベクトル化のために推奨されるループ構造
9.13 restrict
8.41 --cpu=list
8.42 --cpu=name コンパイラオプション
8.62 --diag_warning=tag[,tag,...]
10.6 __forceinline
8.86 --fpmode=model
10.8 __inline
8.139 -Onum
8.144 -Otime
8.164 --restrict、--no_restrict
10.131 __promise コンパイラ組み込み関数
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.