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.

[参考译文] CCS/TMS320F28069:在哪里可以实现2个实数向量的卷积?

Guru**** 2535750 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/599096/ccs-tms320f28069-where-is-the-library-to-implement-the-convolution-of-2-real-vectors

器件型号:TMS320F28069
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

大家好

目前、我们使用 C2000 MCU 来执行闭环控制、我们发现浮点乘法不是那么快

因此、我们将找到卷积库以使其计算速度更快。

下面是我们当前用于计算卷积的方法:

float x1buf[顺序]、x2buf[顺序];

float tmp1;

tmp1 = 0.0f;
PF1 = x1buf;PF2 = x2buf;
for (i=0;<ORDER; i++) {
tmp1 +=*pF1 **pF2;// X1X2
PF1++;PF2++;  

有人是否有更好的代码?

谢谢。

Bobby

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

    您好、Bobby、

    您能否澄清一下您在浮点乘法方面遇到了什么问题?  F28069具有硬件支持、因此您应该已经看到了良好的性能。

    对于闭环控制、卷积类型补偿器的阶数通常为低-两个或三个。  我们在数字控制库中有用于这些低阶类型的示例代码、这些代码应该在 F28069上非常高效地运行。
    您可以在 C2000Ware 中下载该库的 v2.0、网址为 :http://www.ti.com/tool/c2000ware

    如果您需要高阶卷积、FPU DSP 库(也在 C2000Ware 中)中有代码会将两个实数向量相乘。  函数为:MPY_SP_RVxRV_2 ()。  

    基准为: 周期数= 3*N + 17个周期(包括调用和返回)

    此致、

    Richard

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

    你(们)好 Richard

    感谢你的答复。

    我从您提供的网站下载了该文件、文件名是

    C2000Ware_1_00_01_00_setup.run、我无法在 WinXP 笔记本电脑上运行它、然后使用重命名它

    C2000Ware_1_00_01_00_setup.exe、但门槛无法运行、您有什么想法。

    在我发布问题之前、我已经尝试 了 DSP 库中的函数 mpy_SP_RVxRV_2 ()、但它与什么不同

    这是该函数的原型

    void mpy_SP_RVxRV_2 (float32 * y、const float32 * w、 const float32 * x、const uint16 N)

    它用于计算 Y [i]= W [i]∗X[i]

    输出 y 也是一个向量、在这个函数之后、被称为 i 累加了 y 向量中的所有项

    但它花费的时间比我的代码多:

    float tmp=0.0f;

    float *pf1=w,*pF2=x;

    对于(i=0;i<128;i++){

    tmp+=*pF1 **pF2;

    PF1++;PF2++

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

    您好、Bobby、

    DSP 应该能够非常高效地执行这类操作。  您的代码需要多少个周期?

    我附加了一个汇编文件、我认为该文件可以满足您的需求、并附带一个 C 头文件。  在源代码中、我声明了以下变量:

    float pVec[default_vector_size];
    float qVec[default_vector_size];
    浮点 RLT = 0.0f;
    unsigned int i;

    然后调用如下函数:

     (i=0;<DEFAULT_VECTOR_SIZE; i++)
       {
           pVec[i]=(浮点) i;
           qVec[i]= 1.0f;
       }

       RLT = dotp (&pVec[0]、&qVec[0]、default_vector_size);

    对于长度为128的向量、它在163个周期内运行、包括函数调用开销。  如果需要、您可能还可以从其中挤出几个周期。  为此、您需要将矢量分配给不同的物理内存块。  这样做非常简单、如果您不确定、请告诉我。

    但愿这对您有所帮助。

    此致、

    Richard

    e2e.ti.com/.../dotp.asm

    e2e.ti.com/.../dotp.h

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

    你(们)好 Richard

    我已经尝试过您的代码、并获得了令人惊叹的结果。

    下面是我用 C 语言编写的代码、它计算6个矢量 dotp 并使用112us、我使用示波器测量了时间

    #define CZ_Order 128

    //使用112us
    for (i=0;<CZ_ORDER ; i++) {  
    tmp1 +=* pF1 ** pF3;// y2c21
    tmp2 +=* pF2 ** pf4;// y3c31

    tmp3 +=* pF1 ** pf5;// y2c22
    tmp4 +=* pF2 ** pf6;// y3c32

    tmp5 +=* pF1 ** pf7;// y2c23
    tmp6 +=* pF2 ** pf8;// y3c33

    PF1++;PF2++;PF3++;PF4++;
    PF5++;PF6++;PF7++;pf8++;

    然后我使用下面的代码、它只使用12US、我简直不敢相信

    tmp1 = dotp (y2buf、cz21buf、cz_order);

    // Y3C31
    tmp2 = dotp (y3buf、cz31buf、cz_order);

    // Y2C22
    tmp3 = dotp (y2buf、cz22buf、cz_order);

    // Y3C32
    tmp4 = dotp (y3buf、cz32buf、cz_order);

    // Y2C23
    tmp5 = dotp (y2buf、cz23buf、cz_order);

    // Y3C33
    tmp6 = dotp (y3buf、cz33buf、cz_order);

    非常感谢、但在我的代码中提出了另一个问题、我需要对 1个项目执行数组右移、如下代码所示:

    #define CZ_Order 128

    float x1buf[CZ_order ];

    unsigned int i;

    for (i=(CZ_order-1);i>0;i--){
    x1buf[i]= x1buf[i-1];

    在 C 代码中使用112us 进行六向量右移位、需要大量时间、但我找不到任何合适的库函数来实现这一点、您是否仍然有一些更快的惊人 asm 代码?

    此致

    Bobby

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好 Richard
    我使用的 MCU 具有 CLA、我还使用它进行矢量多计算、
    这里是我在 C 语言中执行相同操作的代码、只有3个向量 dotp 使用100us (比 CPU 慢得多)
    // 100us,计算 y1c11、y1c12、y1c13
    #define CZ_Order 128
    _interrupt void Cla1Task1 (void)

    易失性 uint16 i;
    volatile float *pf、*pf1、*pF2、*pf3;

    y1c11 = y1c12 = y1c13 = 0.0f;
    PF = y1buf;
    pf1 = cz11buf;
    pf2 = cz12buf;
    pf3 = cz13buf;
    for (i=0;<CZ_ORDER; i++) {
    y1c11 +=*pf **pf1;
    y1c12 +=*pf **pF2;
    y1c13 +=*pf **pf3;
    PF++;
    PF1++;PF2++;PF3++;


    我还能在 CLA 中使用 dotp asm 代码来使其计算更快吗?

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

    您好、Bobby、

    我已经修改了 dotp.asm 文件、以便在点积运行后移动其中一个数据缓冲区。  您将在 附加文件的上下文恢复部分的正上方看到额外的代码行。  我使用了一个块重复、 这个块重复并不是那么高效、但是整个函数在 F28069上的运行时间仍然低于15us。

    CLA 的指令集略有不同、因此您不能仅在 该内核上运行相同的代码。  它需要单独编写和测试。

    您可以使用一些技巧来帮助 C 编译器、但老实说、要获得这种周期效率、您必须在汇编语言中进行编码。  我建议您仔细浏览"dotp"示例、了解其工作原理、然后根据您的需求进行调整。  如果您想使用 CLA、我建议查看 C2000Ware 中的控制库代码示例:http://www.ti.com/tool/c2000ware。  如果您有任何疑问、随时可以在此处发帖提问。

     每个指令集的技术参考为:

    CPU: http://www.ti.com/lit/ug/spru430f/spru430f.pdf

    FPU: http://www.ti.com/lit/ug/sprueo2b/sprueo2b.pdf

    CLA: http://www.ti.com/lit/ug/spruge6b/spruge6b.pdf

    我认为软件团队没有任何计划很快就添加类似这样的卷积代码、但如果他们有的话、我会要求他们在这里发布。

    但愿这对您有所帮助。

    此致、

    Richard

    e2e.ti.com/.../1512.dotp.asm

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

    你(们)好 Richard

    我已经尝试过您的右***一个浮点矢量的代码,如下所示

    对于(i=0;i<384;i++){
    czbuf1x[i]= 1.0+0.1f*i;

    LED_ON();
    Shiftarray (czbuf1x、czbuf2x、384);
    LED_OFF ();

    我用示波器来显示时间周期为55.6us、但缓冲器 czbuf1x 项目没有正确地移动一个、它们只是停留在、

    我有什么问题吗?

    我按如下方式更改了阵列 ASM 代码:

    ; dotp.asm -浮点向量点积

    ;p =向量1 [XAR4]
    ;q =向量2 [XAR5]
    ;N =向量长度[AL]- N 必须为偶数
    ;返回[R0H]

    .def _Shiftarray;定义 C 可调用标签

    .text
    移位数组(_P):
    asmfunc
    ;上下文保存
    ASP
    按 XAR7
    MOV32 * SP++、R2H
    MOV32 * SP++、R3H
    MOV32 * SP++、R6H
    MOV32 * SP++、R7H

    ;初始化
    MOVL XAR7、XAR5
    SubB AL、#1
    R2H 为零
    R3H 为零
    R6H 为零
    R7H 为零

    ;右移环路
    MOVL XAR7、XAR4
    MOVL P、*- XAR7
    .align 2.
    RPTB _RT_SHIFT_END、AL
    MOVL P、*- XAR7
    MOVL *- XAR4、P
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    _rt_shift_end:

    ;上下文恢复
    MOV32 R7H、*- SP、UNCF
    MOV32 R6H、*- SP、UNCF
    MOV32 R3H、*- SP、UNCF
    MOV32 R2H、*- SP、UNCF
    弹出 XAR7
    NASP
    LRETR
    endasmfunc

    .end

    ;文件结束

    此致

    Bobby

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

    代码通过从远端(最高地址)反向通过数组来执行右移。 这在我发送的文件中起作用、因为 XAR4中的指针已经在数组的远端、而这是因为 RPTB 循环前面有 MACF 循环、MACF 循环通过执行点积的数据前进。

    在上面的代码中没有 MACF 循环、所以 XAR4中的起始地址是数组的起始地址、而不是结束地址。 如果您在 RPTB 行上放置一个断点、并查看 XAR4、您应该会看到这一点。 我不知道哪些数据正在右移、但它不在数组中。

    在将 XAR4分配给 XAR7之前、您需要将其设置为数组的结束地址、然后代码应该可以正常工作。

    此致、

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

    您好 Richard、

    是的、您是对的、当我将数组的末尾传递到 asm 代码时、它现在就可以工作了。

    我想根据您的代码执行更多的 asm 代码、但我不确定如何将参数从 c 代码传输到 asm 代码、您是否知道一些介绍此标尺的文档。

    此致

    Bobby

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

    您好、Bobby、

    汇编接口记录在 C 编译器用户指南的第7.5节中、如下所示:

    http://www.ti.com/lit/ug/spru514n/spru514n.pdf

    我附加了一个示例文件、其中显示了用于传递调用参数和返回参数的寄存器。  您可能不需要所有上下文保存/恢复内容-这只是一个示例。  希望这对您有所帮助。

    此致、

    Richard

    e2e.ti.com/.../asmfunc.asm