double を使用する C コードがあります。DSP ( TMS320 )でコードを実行できるようにしたい。ただし、DSP は double をサポートせず、固定小数点数のみをサポートします。コードを固定小数点に変換する最良の方法は何ですか? 固定小数点数 (整数として実装) 用の優れた C ライブラリはありますか?
5 に答える
次のコードは、内部表現として整数を使用して Fixed 型を定義します。加算と減算は、+
and-
演算子で簡単に実行できます。乗算は、定義されたMULT
マクロを使用して実行されます。
#include <stdio.h>
typedef int Fixed;
#define FRACT_BITS 16
#define FRACT_BITS_D2 8
#define FIXED_ONE (1 << FRACT_BITS)
#define INT2FIXED(x) ((x) << FRACT_BITS)
#define FLOAT2FIXED(x) ((int)((x) * (1 << FRACT_BITS)))
#define FIXED2INT(x) ((x) >> FRACT_BITS)
#define FIXED2DOUBLE(x) (((double)(x)) / (1 << FRACT_BITS))
#define MULT(x, y) ( ((x) >> FRACT_BITS_D2) * ((y)>> FRACT_BITS_D2) )
上記のコードを使用して、画像処理アルゴリズムで分数を表していました。double を使用していたバージョンよりも高速で、結果はほぼ同じでした。
TI は、「IQmath」と呼ばれる固定小数点ライブラリを提供しています。
http://focus.ti.com/lit/sw/sprc990/sprc990.pdf
変換には、現在のコードの分析が含まれます。変数ごとに、保持できる範囲と必要な精度を知る必要があります。IQMath は、範囲が +/-2 で精度が 0.0000000001 の q30 から、範囲が ~+/- 100 万で精度が 0.5 の q1 までの型を提供します。
変数の範囲をオーバーフローする可能性のある操作については、オーバーフローのチェックを追加し、それを処理する方法を決定する必要があります-最大で固定する、別のスケールで保存する、エラーを発生させるなど.
プロセスのデータフローを深く理解することなく、固定小数点に変換する方法はありません。
ほとんどの DSP ツールチェーンには、ソフトウェアでの浮動小数点エミュレーション用のライブラリが含まれています。これは遅くなりますが、最初に浮動小数点サポートを使用してコードをビルドし、次にプロファイリングして、十分なパフォーマンスを得るために固定小数点に変換する必要がある場所がいくつかあるかどうかを確認する必要があります。また、固定小数点に移植するときに比較を行い、その過程で何も失われていないことを確認するために、浮動小数点のものを実行する必要があります。
C コードが double をほとんど/まばらにしか使用しない場合、C コードの実行速度を 10 倍から 100 倍遅くすることなく、浮動小数点エミュレーション ライブラリを使用できる可能性があります。パフォーマンスの低下を望まず、多くの浮動小数点演算があり、実際の入力ごとにすべての算術演算と格納演算に必要なスケールと精度がわかっている場合は、各算術演算を手動で次のように変換できます。スケーリングされた整数データ型と演算を使用しました。しかし、精度要件の分析は、一般に、DSP タイプのコードでは簡単ではありません。DSP と Numerical Methods の教科書には、このテーマに関する多くの章があります。
これを行うライブラリがいくつかあります。ただし、デバイスの PSP には何らかの数学ライブラリが含まれている可能性が高くなります。文書化する必要があります。PSP が提供する API を使用すると、プリミティブベースの浮動小数点演算を行うときに使用する制御構造が意味をなさない可能性があるため、コードの一部を書き直す必要がある可能性があります。
たとえば、これを変換できます
double arraysum = 0.0;
for (int i = 0; i < arraylen; i++)
{
arraysum += array[i];
}
これに
psp_decimal_t arraysum;
if (0 != psp_sum_elements(&array, arraylen, &arraysum))
{
printf("error!");
}