我有一个使用双打的C代码。我希望能够在DSP(TMS320)上运行代码。但DSP不支持双精度数,只支持定点数。将代码转换为定点的最佳方法是什么?是否有一个好的C库用于定点数(实现为整数)?
答案 0 :(得分:12)
以下代码定义了一个类型Fixed,使用整数作为其内部表示。只需使用+
和-
运算符即可执行加法和减法。使用定义的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) )
我使用上面的代码来表示我的图像处理算法中的分数。它比使用双打的版本更快,结果几乎完全相同。
答案 1 :(得分:8)
TI提供名为“IQmath”的定点库:
http://focus.ti.com/lit/sw/sprc990/sprc990.pdf
转换涉及分析当前代码 - 对于每个变量,您需要知道它可以容纳的范围,以及它需要的精度。然后您可以决定将其存储在哪个类型中.IQMath提供q30中的类型,范围为+/- 2,精度为0.0000000001到q1,范围为〜+/- 1百万,精度为0.5。
对于可能溢出变量范围的操作,您需要添加溢出检查,并决定如何处理它 - 将其固定为最大值,以不同的比例存储,引发错误等等。
如果没有真正深入了解流程的数据流,就无法转换为固定点。
答案 2 :(得分:5)
大多数DSP工具链包括用于软件中浮点仿真的库。这将是缓慢的,但您应该首先使用浮点支持构建代码,然后配置文件以查看是否只需要转换为定点以获得足够性能的几个位置。当你移植到定点时,你还需要运行浮点内容来提供比较,以确保你没有在过程中丢失任何东西。
答案 3 :(得分:2)
如果C代码很少/稀疏地使用双精度数,那么您可以使用浮点仿真库,而不会导致C代码运行速度慢10到100倍。如果不希望性能受到影响并且存在大量浮点运算,并且您知道每个算术和存储操作对于每个实际输入所需的比例和精度,那么您可以手动将每个算术运算转换为使用缩放的整数数据类型和操作。但是,分析精度要求通常对DSP类型代码来说并不重要。关于这一主题有许多DSP和数值方法教科书章节。
答案 4 :(得分:0)
有一些图书馆可以为你做这件事。但是,更有可能的是,您的设备的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!");
}