13

我有一个使用双精度的 C 代码。我希望能够在 DSP ( TMS320 ) 上运行代码。但是 DSP 不支持双精度数,只支持定点数。将代码转换为定点的最佳方法是什么?是否有用于定点数(以整数实现)的良好 C 库?

4

5 回答 5

13

以下代码定义了一个固定类型,使用整数作为其内部表示。加法和减法只需使用+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) )

我使用上面的代码来表示我的图像处理算法中的分数。它比使用双打的版本更快,结果几乎完全相同。

于 2011-03-21T11:54:03.280 回答
8

TI 提供了一个名为“IQmath”的定点库:

http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

转换涉及分析您当前的代码 - 对于每个变量,您需要知道它可以容纳什么范围,以及它需要什么精度。然后您可以决定将其存储在哪种类型中。IQMath 提供从 q30 范围为 +/-2 且精度为 0.0000000001 到 q1 的类型,范围为 ~+/- 100 万和精度为 0.5。

对于可能溢出变量范围的操作,您需要添加溢出检查,并决定如何处理它 - 将其固定在最大值,以不同的比例存储,引发错误等。

如果不真正深入了解流程的数据流,就真的没有办法转换为定点。

于 2010-12-06T20:03:20.877 回答
5

大多数 DSP 工具链包括软件中的浮点仿真库。这会很慢,但您应该首先构建具有浮点支持的代码,然后分析以查看是否只有少数地方需要转换为定点以获得足够的性能。您还需要运行浮点数据以在移植到定点时提供比较,以确保您在此过程中没有丢失任何内容。

于 2010-12-06T16:24:22.757 回答
2

如果 C 代码很少/很少使用双精度数,那么您可能能够使用浮点仿真库,而不会导致 C 代码运行速度慢 10 倍到 100 倍。如果不希望性能受到影响并且有很多浮点运算,并且您知道每个实际输入的每个算术和存储操作所需的比例和精度,那么您可以手动将每个算术运算转换为使用缩放的整数数据类型和操作。但是,对于 DSP 类型代码,分析精度要求通常并非易事。有许多关于该主题的 DSP 和数值方法教科书章节。

于 2010-12-06T17:11:20.710 回答
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!");
}
于 2010-12-06T16:25:26.533 回答