This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320C6678:如何了解 c66x DSP 应用手册中优化环路的示例?

Guru**** 2539500 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/941435/tms320c6678-how-to-understand-the-example-in-optimizing-loops-on-the-c66x-dsp-application-note

器件型号:TMS320C6678

您好、香榭丽舍

客户对 c66x DSP 应用手册中优化环路部分3.1.5中的示例有一些疑问。  
https://www.ti.com/lit/an/sprabg7/sprabg7.pdf

void example_gc (cplxf_t * a、cplxf_t * ejalpha、float * abs_a、int n)


int i;
float a_sqr、oneOverAbs_a;
对于(i = 0;i < n;i++)

a_sqr =a[i].Real * a[i].Real + a[i].imag * a[i].imag;
oneOverAbs_a =1.f/(float) sqrt (a_sqr);
abs_a[i]= a_sqr * oneOverabs_a;
ejalpha[i].Real =a[i].Real * oneOverAbs_a;
ejalpha[i].imag =a[i].imag * oneOverAbs_a;



优化代码如下所示:

_nassert (n % 4 = 0);
_nassert (((int) a % 8 = 0);
_nassert (((int) ejalpha % 8 = 0);
_nassert (((int) abs_a % 8 = 0);
#pragma MUST_ITERATE (4、100、4);
#pragma UNROLL (2);
对于(i = 0;i < n;i++)

a_sqr = a[i].Real * a[i].Real + a[i].imag * a[i].imag;
oneOverAbs_a =_rsqrsp (a_sqr);/* 1/sqrt ()指令8位尾数精度*/
/*一个内插*/
oneOverAbs_a = oneOverAbs_a *(1.5f -(a_sqr/2.f)* oneOverAbs_a * oneOverAbs_a);
abs_a[i]= a_sqr * oneOverabs_a;
ejalpha[i].Real =a[i].Real * oneOverAbs_a;
ejalpha[i].imag =a[i].imag * oneOverAbs_a;


问题:

以下两条指令的含义是什么?
oneOverAbs_a =1.f/(float) sqrt (a_sqr);
abs_a[i]= a_sqr * oneOverabs_a;

2.优化后,代码按如下方式更改:
oneOverAbs_a =_rsqrsp (a_sqr);/* 1/sqrt ()指令8位尾数精度*/
/*一个内插*/
oneOverAbs_a = oneOverAbs_a *(1.5f -(a_sqr/2.f)* oneOverAbs_a * oneOverAbs_a);
rsqrsp

为什么将 oneOVerAbs_A 更改为 oneOverAbs_a *(1.5f -(a_sqr/2.f)* oneOverAbs_A * oneOverAbs_a);
rsqrsp?

3.什么是 e jangle (A[i])?

谢谢。
Rgds
闪亮



  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您可能知道、除法是一种无人喜欢的指令、因为它通常由 RTS 子例程调用实现。 这实际上会使循环脱离流水线优化和归零优化工作。 当我们在循环中看到除法指令时、会弹出"we do it here" meme 图片。

    由于分裂在现实生活中往往是不可避免的,我们必须为此发明一些明智的补救办法。 一种方法是使用乘法反向。 它上有 wiki、但以简单的方式、人们可能会考虑以下方式。 假设必须计算一些类似 A/B 的内容 这里用 B 除以。那么想象一下我们可以提前知道1/B 系数,所以不是 A/B,而是可以计算出 A*(1/B)。 从数学角度来说、两者都是等效的、但在后一个除法中、乘法被乘法取代、而乘法是 DSP 在中的强大功能。

    因此、如果提前知道除数、则可以选择乘法反向。 但我们并不总是那么幸运。 因此、如果必须除以原始未知除数、则该技术将不起作用。 在本例中、我们仍然避免除法、因为它将是新冠。 一种方法是用牛顿近似循环(参考 https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division)替换精确(我是指无近似)的单除法指令、即乘法次数和求和次数。 DSP 就是这样一种野兽、在流水线循环中进行这些乘法和求和可能比 RTS 除法例程更高效。

    最后、C66内核具有专用硬件块、可计算1/x 或1/sqrt (x)的近似值。 这些块通过 C 内在函数进行访问、并为我的存储器提供8个良好的尾数位。 单精度浮点具有23位尾数、因此很显然、近似值并不是很好。 因此、如果需要更高的精度、仍然可以使用内在函数输出作为初始近似值来进行牛顿迭代。 也许您在数字方法课程中还记得、牛顿方法通常通过检查条件来实现、是否实现了所需的精度。 在本文档中、您引用我们已经计算出的值、两次迭代将产生足够的尾数精度、因此一个代码只需两个牛顿步长即可完成、无需检查。

    同样适用于1/sqrt (x)指令。 复数标准化通常需要该参数。

    希望这对您有所帮助。