論理演算式の最適化 - 2023.2 日本語

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 日本語

合成中は、駆動電流の削減やビット幅の最小化など、複数の最適化が実行されます。自動最適化には、演算式バランス調整も含まれます。

演算式バランス調整では、演算子を並べ替えてバランスの取れたツリーを構築することにより、レイテンシを削減します。

  • 整数演算の演算式バランス調整はデフォルトでオンになっていますが、EXPRESSION_BALANCE プラグマまたは指示子を使用してオフにできます。
  • 浮動小数点演算では、演算式バランス調整はデフォルトでオフになっていますが、次のように config_compile -unsafe_math_optimizations コマンドを使用すると、オンにすることもできます。

たとえば、+= および *= などの代入演算子を使用した (またはループ展開の結果の) 次のようなシーケンシャル コードがあるとします。

data_t foo_top (data_t a, data_t b, data_t c, data_t d)
{
 data_t sum;

 sum = 0;
 sum += a;
 sum += b;
 sum += c;
 sum += d;
 return sum;

}

演算式バランス調整が実行されない場合、各加算に 1 クロック サイクルが必要だとすると、次の図に示すように sumsum の計算に 4 クロック サイクルかかります。

図 1. 加算器ツリー

ただし、加算 a+b および c+d は並列実行できるので、レイテンシを削減できます。このように計算のバランスが調整されると、計算は 2 クロック サイクルで終了します。演算式バランス調整を使用すると共有はできず、エリアは増加します。

図 2. バランス調整後の加算器ツリー

整数に対しては、EXPRESSION_BALANCE 最適化指示子を off に設定すると、演算式バランス調整をオフにできます。デフォルトでは、HLS ツールは float または double 型の演算に対しては EXPRESSION_BALANCE 最適化を実行しません。float および double 型の合成では、C/C++ シミュレーションと結果が同じになるように、C/C++ コードで実行される演算順序が維持されます。たとえば、次のコード例では、すべての変数が float または double 型です。O1 および O2 は、同じ基本的な計算を実行しているように見えますが、値は同じではありません。

A=B*C; A=B*F;
D=E*F; D=E*C;
O1=A*D O2=A*D;

これは、float または double 型の演算における C/C++ 標準の飽和および丸めの結果です。このため、HLS コンパイラでは float または double 型の変数が使用され、デフォルトで演算式のバランス調整が実行されない場合、演算の順序が常に維持されます。

特定の演算に対して演算式バランス調整をオンにしたり、syn.compile.unsafe_math_optimizations=1 コンフィギュレーション コマンドを使用して float および double 型の演算で演算式バランス調整をオンにしたりできます。

この設定をオンにすると、さらに最適なデザインが生成されるように演算の順序が変更されることがありますが、C/RTL 協調シミュレーションの結果が C/C++ シミュレーションと異なるものになる可能性があります。

unsafe_math_optimizations を使用すると、syn.compile.no_signed_zeros 最適化も有効になります。no_signed_zeros 最適化により、float および double 型を使用した次の演算式が同一になります。

x - 0.0 = x; 
x + 0.0 = x; 
0.0 - x = -x; 
x - x = 0.0; 
x*0.0 = 0.0;

no_signed_zeros 最適化が使用されない場合は、丸めが実行されるので、上記の演算式は同一になりません。この最適化は、syn.compile.no_signed_zeros コンフィギュレーション コマンドのみを選択すると、演算式バランス調整なしで使用できます。

ヒント: unsafe_math_optimizations および no_signed_zero 最適化が使用されると、RTL インプリメンテーションが C/C++ シミュレーションとは異なる結果になります。テストベンチでは、結果の多少の違いは無視できるので、範囲を確認し、厳密には比較しないでください。