13

我有一個使用雙打的C代碼。我希望能夠在DSP上運行代碼(TMS320)。但DSP不支持雙打,只支持定點數字。將代碼轉換爲定點的最佳方式是什麼?定點數字是否有一個好的C庫(作爲整數實現)?如何將浮點C代碼轉換爲固定點?

+3

這是一個很大的話題。在這個SO問題中有一個很好的討論:http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math。幾乎所有的答案都有一些有用的金塊。 – mtrw 2010-12-06 16:20:15

+1

出於好奇,DSP的編譯器如何表示固定點?作爲兩個整數?例如,你如何將兩個定點數加在一起? – chrisaycock 2010-12-06 16:21:44

+0

它們被表示爲32位值(`long`),並且類型中隱含有一個移位。例如,如果在點(`_iq16`)之後有16位,則在基礎類型中用整數65536表示定點數字1.0。要添加和減去同一類型的定點數,可以使用標準整數運算。乘法需要額外的改變來校正縮放。 – starblue 2014-01-09 13:44:48

回答

8

TI提供了一個名爲「IQMATH」定點庫:

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

轉換包括分析當前的代碼 - 每個你需要知道的範圍內它可以容納可變的,它需要什麼精密。然後,您可以決定將其存儲在哪種類型中。IQMath提供q30中的類型,範圍爲+/- 2,精度爲0.0000000001至q1,範圍爲+/- 1百萬,精度爲0.5。

對於那些可能溢出變量的範圍內,你需要增加檢查溢出,並決定如何處理它的操作 - 在最大,存儲與不同的刻度針它,引發錯誤等

如果沒有真正獲得對流程數據流的深刻理解,真的沒有辦法轉換爲定點。

5

大多數DSP工具鏈都包含用於軟件浮點仿真的庫。這會很慢,但您應該首先使用浮點支持構建您的代碼,然後通過配置文件查看是否有幾個位置需要轉換爲定點以獲得足夠的性能。您還需要運行浮點運算以在您進入固定點時提供比較,以確保您在進程中沒有丟失任何內容。

0

有幾個圖書館可以爲你做這個。然而,更有可能的是,你的設備的PSP應該包含某種數學庫。它應該被記錄。您可能需要重新編寫一些代碼,因爲當您使用由PSP提供的API時,執行基於原始的浮點運算時使用的控件結構可能沒有意義。

例如 - 你可能如果C代碼使用雙打很少/稀疏,那麼你可能能夠使用浮點仿真庫轉換這個

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!"); 
} 
+0

鏈接已死,請更正。 – Danijel 2017-06-27 08:59:08

2

而不會導致你的C代碼運行速度慢10倍到100倍。如果不希望性能受到影響,並且存在大量浮點運算,並且您知道每個算術運算和存儲操作對於每個實際輸入所需的規模和精度,則可以手動將每個算術運算轉換爲使用縮放整數數據類型和操作。但對於DSP類型代碼來說,分析精度要求一般來說並不重要。有關該主題的許多DSP和數值方法教科書章節。

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

我正在使用上面的代碼來表示我的圖像處理算法中的分數。它比使用雙打的版本更快,結果幾乎完全相同。