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.

[参考译文] TDA4VM:C7x 培训

Guru**** 1791630 points
Other Parts Discussed in Thread: PROCESSOR-SDK-J721E
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/992238/tda4vm-c7x-training

器件型号:TDA4VM
主题中讨论的其他器件:PROCESSOR-SDK-J721E

您好!

我下载了版本0.5的 C7x 培训,该培训来自 PROCESSOR-SDK-J721E v6.1页面: PROCESSOR-SDK-RTOS-J721E_06.01.01.12 | TI.com

此培训的新版本是否可用或已计划? 如果有计划、您能否提供大致的供货日期?

在此新版本中、高级示例是否包含其文档?

现在是否可以获得这些示例的文档、即使尚未完成也是如此?

FFT 示例(c7x_fft1d_16bit)对我有很大的兴趣、但没有文档甚至评论。

非常感谢、
克莱蒙特

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

    关于同一主题,我借此 机会 同时发表这篇文章:我以线性方式排列了16个数据,我想用 这种形状创建4个向量:



    我 感觉流引擎不允许 进行组复制 、而是用一个组填充矢量、而在这里、我有两个组用于一个矢量(矢量1为0 1、矢量1为4 5)。

    元素的复制也不起作用(我不想0 1 1、而是0 1 0 1)。

    因此、我尝试使用几个维度手动执行此操作:

    params0.TRANSPOSE =__SE_TRANSPOSE_128位;

    params0.ICNT0 = 2;
    params0.ICNT1 = 2;params0.DIM1 = 0;
    params0.ICNT2 = 2;params0.DIM2 = 4;
    params0.ICNT3 = 2;params0.DIM3 = 1;
    params0.ICNT4 = 2;params0.DIM4 = 8;

    这是转置的方式,但我以前是以正常方式尝试的,但问题是相同的:由于边界感知和 ICNT1 = 2,我得到了空的半向量

    那么,我的问题是:是否可以使用 SE 构建这些矢量? 如果不是,构建它们的最佳方法是什么 ?

    非常感谢您的观看、

    Cl é ment FAUCONNET

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

     您好、Cl é ment、

    我没有连接到文档/培训、因此我无法在那里评论您的问题、但我可以提供有关 SE/C7x 编程以及如何获取您所需的模式的信息。

    您正处于转置模式的正确轨道上! 遗憾的是、在线性模式下、没有创建您正在处理的图形的机制、因此如果要完全包含在 SE 中、则需要使用转置模式。

    要创建此模式、您需要执行的操作是:

    • 将转置粒度(TRANSPOSE)设置为元素大小的2倍。 您似乎在对可能的64位元素进行128位粒度的处理。
    • 将 ELTYPE 设置为复杂、因此元素0'将具有子元素(0、1)、1'将具有(2、3)、2'将具有(4、5)等
    • 将 ELDUP (元素复制)设置为2x

    如果您使用 ICNT1、2、3、4、5 = 1运行此操作、则会看到一个仅包含0101的向量。 要获得01014545、请设置 ICNT1=2和 DIM1=4、以便第二个"行"从元素4开始。

    更多参数:

    • ICNT0=2 (转置模式的效率与 ICNT0内颗粒与行数之比相关。 我将其从您的 ICNT3移到这里)
    • ICNT1 = 2;DIM1 = 4
    • ICNT2 = 2;DIM2 = 8
    • ICNT3、4、5 = 1

    不过、这种方法存在局限性。 存在 SE 硬件限制、因此16位转置粒度需要2个元素类型升级、因此如果没有后处理、1B 元素将无法工作。 此外、由于这利用了复杂的元素类型、因此它仅适用于重复连续元素对的模式。 例如、如果您需要0123_0123_89AB_89AB、这是不可能的。

    如果您发现自己需要创建更广义的图形、那么您还可以查看 C7x 的 VPERM 指令。 下面简要概述了您将如何将其用于此方案:

    将元素0-7 (假设为64位元素)读取为来自 SE 的一个向量。

    将其作为第二个输入传递到 VPERM (您可以使用__permute (uchar64、uchar64)内在函数)。 VPERM 的第一个输入是一个数组、其中每个字节指示相应输出字节来自输入矢量中的哪个位置以及一些格式信息。 在这种情况下、您的阵列将是:

    然后、将其环回。 将 SE 的寻址参数设置为以下、您可以为每个矢量重复使用相同的排列图:

    • 6 <= ICNT0 <= VECLEN (至少需要6个元素才能得到0、1、4和5。 我将 VECLEN 作为上限、因为您希望 ICNT0完全包含在一个矢量中)
    • ICNT1 = 2;DIM1 = 2
    • ICNT2 = 2;DIM2 = 8
    • ICNT3、4、5 = 1

    与使用 SE 的转置模式相比、这具有一些优势:

    1. 可用于创建更复杂的图形、并避免 SE 对小颗粒的硬件限制
    2. 根据最终代码和编译器能够实现的调度、这可能会更快地运行、因为 SE 在线性模式下运行时比在转置模式下更高效、并且开销更小。

    此致、

    Burton

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

    伯顿、

    首先、非常感谢您的参与、您的回答对我非常有帮助!

    1) 1)您的解决方案是明智的、但我没有指定:我的输入矢量的每个元素都是一个64b 的复数。  很抱歉、我不是很精确、但我认为这些信息对您来说不重要、我想让问题变得更简单。

    另一方面、我不太了解 VPERM、我确实认为这可以是一种解决方案、我认为我会通过使用它来完全丧失性能、谢谢。

    2) 2)您讨论了 SE 在转置模式下的问题、实际上我最近遇到了一个问题、我不得不解决这个问题、我想告诉您、因为我在文档中没有看到相关内容:

    这里是 SE:  

    __SE_TEMPLATE_v1参数 s1 =__gen_SE_TEMPLATE_v1 ();
    params1.ELETYPE =__SE_ELETYPE_32BIG_CMPLX_SWaP;
    params1.DIMFMT =__SE_DIMFMT_3D;
    params1.TRANSPOSE =__SE_TRANSPOSE_64位;
    params1.VECLEN =__SE_VECLEN_8ELEMS;

    params1.ICNT0=1;
    params1.ICNT1 = ptByButterfly;        params1.DIM1 =蝴蝶;
    params1.ICNT2 =蝴蝶;            params1.DIM2=0;


    如果 ptByButterfly 严格大于16、此流引擎会崩溃。

    因此、我必须这样写:

    __SE_TEMPLATE_v1参数 s1 =__gen_SE_TEMPLATE_v1 ();
    params1.ELETYPE =__SE_ELETYPE_32BIG_CMPLX_SWaP;
    params1.DIMFMT =__SE_DIMFMT_3D;
    params1.TRANSPOSE =__SE_TRANSPOSE_64位;
    params1.VECLEN =__SE_VECLEN_8ELEMS;

    params1.ICNT0=1;
    params1.ICNT1 = 16;                 params1.DIM1 =蝴蝶;
    params1.ICNT2 = ptByButterfly/16;       params1.DIM2=16*蝴蝶;
    params1.ICNT3 =蝴蝶;             params1.DIM3=0;

    我发现这很奇怪、但可能我在文档中遗漏了一些内容。

    3) 3)最后、我有一个问题:


    在我的算法中、我目前使用的是传统 FFT 代码、我从 VSTBITRDW 指令所执行的位反转地址步开始。 指令使用的大小一定是有限的(向量的大小)、如果您的输入大于向量、则它将不起作用、因为它需要所有元素重新排列它们。 您是否可以针对任何尺寸以优化的方式进行此操作?

    类似的东西:但是对于大于16的长度,例如512。 仍在使用 __SE_ELETYPE_32BIG_CMPLX

    非常感谢您的帮助、这确实有助于我最大程度地提高 C71x 内核的性能。

    克莱蒙特



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

    克莱门特

    1) 1) 是的、这会使您遇到需要0123012389AB89AB 和 SE 不支持在单个矢量中生成该图形的情况、很遗憾。  

    VPERM 是一个.C 单元专用指令、因此 如果您有多个运算需要在循环中的.C 单元上执行、它可能会对您的性能产生负面影响。 以下是其他几种选择:

    1. 您可以使用两个 SE (如果您尚未同时使用这两个 SE...) 若要通过其中一个矢量(01010000和454545)上的组复制生成矢量的部分、请在第二个矢量(01010000和00004545)上使用和掩码、最后或将它们组合在一起以获得所需的矢量。 这是更多指令、但在可调度的单元方面受限较少、编译器应能够通过将两个运算并行进行安排、将其调度到单周期循环中。 因此、将结果放置在 VB0中的候选汇编可能是:
      • VANDW Se0++、VB1、VB2 <-- VB1是与屏蔽
      • VORW SE1++、VB2、VB0
    2. 您可以尝试对一个 SE 执行相同的操作、这是一种手动软件循环展开(VB1和 VB2是掩码、目的仍然是 VB0)。
      • SE0读取顺序:
        1.  01012323
        2. 45456767
      • 伪代码:
        • FIRST_VEC = SE0++;
        • Sec_VEC = Se0++;
        • first_lower =(first_vec & lower _mask);
        • first_upper =(first_vec & up_mask)>>[32字节];
        • sec_lower =(sec_vec & lower _mask)<<[32字节];
        • sec_upper =(sec_vec & upper _mask);
        • first_output =(first_lower | sec_lower);
        • sec_output =(first_upper | sec_upper);
    3. 如果您当前未使用 MMA、则对其进行编程。 不过、这肯定是一项更涉及的任务。

    2) 2) 要转置数组、必须先读取所有行、然后写出所有列。 要做到所有行都必须从内存中接收、因此必须缓冲已接收的行、这意味着可以操作的最大行数受 IP 中执行转置的存储量的限制。 遗憾的是、SE 仅具有内部存储、可执行16行转置。 其原因是、转置模式针对大型阵列的工作进行了优化、您可以在大型阵列上将阵列分解为类似于您所做的那样的较小的"图块"。 但是、要获得最佳性能、您应该使 ICNT0尽可能大。 下面是一个24x24阵列示例、其中列的宽度为每个64位:

    由于列的宽度为64位、因此您只能在单个矢量中容纳8个列、因此假设您要处理8个行。 SE 生成第一列(8行)时、它将把浅绿色区域提取到其本地存储中、至少需要8个周期。 如果您一路工作、第一列 SE 将不得不丢弃浅绿色区域、以便为您请求数据的下一个图块腾出空间。 当您最终到达顶部的第二列时、SE 必须再次重新获取浅绿色区域。 结果是 SE 将为从其读取的每个矢量执行8次取指令、这意味着大于700%的开销。 性能将会很糟糕。 对于线性模式、您基本上可以让 SE 执行所需的任何模式、而无需考虑性能、但在使用转置模式时需要非常小心  

    为了优化性能、建议在移动到另一个逻辑块之前使用完整的逻辑块、以便 SE 不必重新获取它。 遗憾的是、这意味着您必须对循环和算法进行返工以处理不同的访问模式。 或者、您可以尝试将转置操作移至 MMA、并使用转置矩阵来完成作业。 每个逻辑块的宽度是向量大小(64B)。 此外、如果您的数据未对齐、我强烈建议将 ICNT1限制为不超过8、以便 SE 可以使缓冲区加倍。 如果您保持一致、则 ICNT1 = 8和16之间的性能应相当。

    3) 3) 假设您要执行算法并立即存储结果、下面是针对您的反向地址步骤问题的一些集体讨论:

    最终操作是  VSTBITRDW。

    长度= 8: 需要一个矢量:01234567

    length = 16:目标是创建两个向量:

    1. 02468ACE
    2. 13579BDF

    长度= 32:目标是创建四个矢量:

    1. 0 4 8 C 10 14 18 1C
    2. 1 5 9 D 11 15 19 1D
    3. 2 6 A E 12 16 1A 1E
    4. 3 7 B F 13 17 1B 1F

    等等...

    要创建这些 N 矢量、您可以从 SE 读取 N 个矢量、然后使用静音/交换操作或和/或屏蔽来创建最终矢量、然后调用 VSTBITRDW 将结果写回存储器。 我不知道这是不是最理想的、但这正是我想到的。

    此致、

    Burton

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

    伯顿、

    您的答案非常清楚

    如果我对这一主题有任何疑问或意见、我可能会再次与您联系。

    非常感谢您的支持、这对我们的工作有很大帮助。

    克莱蒙特