如何将浮点 C 代码转换为定点?

发布于 2024-10-06 18:04:14 字数 194 浏览 10 评论 0原文

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

I have a C code which uses doubles. I want to be able to run the code on a DSP (TMS320). But the DSP doesn't support doubles, only fixed-point numbers. What is the best way to convert the code into fixed-point? Is there a good C library for fixed-point numbers (implemented as integers)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陌伤浅笑 2024-10-13 18:04:14

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

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

The following code defines a type Fixed, using integers as its internal representation. Additions and subtractions are performed simply with the + and - operators. Multiplication is performed using the defined MULT macro.

#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) )

I was using the above code to represent fractions in my image processing algorithm. It was faster than the version which was using doubles and the results were almost exactly the same.

爱殇璃 2024-10-13 18:04:14

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

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

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

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

确实没有办法转换为定点,而无需真正深入了解过程的数据流。

TI provides a fixed-point library called "IQmath":

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

Converting involves analyzing your current code - for each variable you need to know what range it can hold, and what precision it needs. Then you can decide which type to store it in. IQMath provides types from q30 with a range of +/-2 and a precision of 0.0000000001 to q1 with a range of ~+/- 1 million and a precision of 0.5.

For operations which can possibly overflow the range of the variables, you need to add checks for overflow, and decide how to handle it - pin it at max, store with a different scale, raise an error, etc.

There is really no way to convert to fixed point without really gaining a deep understanding of the dataflow of your process.

花落人断肠 2024-10-13 18:04:14

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

Most DSP toolchains include libraries for floating-point emulation in software. This will be slow, but you should initially build your code with floating-point support, then profile to see if there are just a few places that you need to convert to fixed-point to get sufficient performance. You will also need to have the floating-point stuff running to provide a comparison as you port to fixed-point, to make sure you haven't lost anything in the process.

复古式 2024-10-13 18:04:14

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

If the C code uses doubles very seldom/sparsely, then you might be able to use a floating point emulation library without causing your C code to run 10X to 100X slower. If don't want that performance hit and there are a lot of floating point operations, and you know the scale and precision required at every arithmetic and store operation for every realistic input, then you might be able convert each arithmetic operation, manually, to used scaled integer data types and operations. But analyzing precision requirements is, in general, non-trivial for DSP type code. There are many DSP and Numerical Methods textbook chapters on the subject.

半葬歌 2024-10-13 18:04:14

有一些图书馆可以为您做到这一点。不过,更有可能的是,您的设备的 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!");
}

There are a few libraries out there that may do this for you. More likely, though, the PSP for your device should include some sort of math library. It should be documented. You will likely have to re-write some your code, because the control constructs you use when doing primitive-based floating-point arithmetic may not make sense when you use the API provided by your PSP.

For example - you might convert this

double arraysum = 0.0;
for (int i = 0; i < arraylen; i++) 
{
    arraysum += array[i];
}

to this

psp_decimal_t arraysum;
if (0 != psp_sum_elements(&array, arraylen, &arraysum))
{
    printf("error!");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文