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.

[参考译文] PROCESSOR-SDK-TDAX:TDA2x:有关 EVE EDMA 时间计算的信息

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/669384/processor-sdk-tdax-tda2x-information-regarding-eve-edma-time-calculation

器件型号:PROCESSOR-SDK-TDAX

您好!

我正在处理640 * 480图像大小、并编写内核以使用 EVE 自动增量用例转置图像。

请注意、我们正在使用非 BAM 框架。

要转置图像、根据我的计算结果、在电路板上花费~0.3m 秒(196000个周期)、花费~1m 秒(650000个周期)、这是不合理的。

根据我们的分析、与 VCOP 处理相比、DMA 需要更多的时间。 为了确保这一点、我们禁用了内核处理、发现 DMA 操作需要~1m 秒

因此、我需要有关任何配置/方法的信息来查找 DMA 近似时间

请建议一些优化 DMA 时间的方法。

请帮我解决这个问题。

此致、

Prashant Kothari

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好普拉什特、
    通常、您可以假设使用 DMA 每字节传输的 VCOP 周期为0.25 VCOP。

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

    感谢您的回复。

    我正在使用_TSC 函数来计算周期。 但是、电路板和仿真器上的周期数不同。

    理想情况下、DMA 所需的时间应更短、内核时间应为执行时间。 但在我的映像中、EDMA 在前台运行(禁用内核处理以了解 DMA 时间)。 这就是为什么、我将有更多的时间来执行它。

    您能否在自动递增用例中建议减少 DMA 时间的机制?

    此致、
    Prashant Kothari
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    如果您使用_TSC 函数来计算周期数、则必须将其乘以2才能获得 VCOP 周期数。 因此、对于输入为640x480的情况、我假设输出大小为480x640、则 DMA 所需的 VCOP 周期总数应为2 *
    (640*480*2)/4。 如果内核周期小于这些周期、则 DMA 将出现在前台。
    现在、这是一个指南、实际的 DMA 周期实际上将取决于 DDR 的整体系统使用情况。 如果还有其他正在运行的算法也在访问 DDR、则周期数可能更高。 通常、如果您在独立模式下运行算法、则 DMA 所花费的周期将接近我们估算的周期。

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

    感谢您的快速响应。

    在上面的周期计算中、我们考虑了乘以2 (VCOP 周期)。

    根据您的建议、我们已禁用所有处理、并且 Transpose 内核独立运行。

    在自动递增用例中、
    初始化时间=~275 μ s
    初始化+ DMA =~1毫秒
    初始化+ DMA +内核=~1.13ms

    理想情况下、我们的计算 DMA 应采用~236uec。 因此、Toal DMA 时间应为(INIT + DMA)~500 μ s。 但是、在本例中、它的取值为~800 μ s。

    如果您可以建议某种方法来优化 DMA 时间、那将会非常棒。

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

    Prashant、

      您能否共享输入和输出通道的 DMA 配置?

    此致、

    安州

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

    下面给出了 DMA 配置和内核处理函数。
    请注意、对于 DMA 输出通道、我们将手动更新外部存储器指针。

    #include
    #include
    #include
    #include
    #include
    #include

    /*------------------ *
    /*这些是 EDMA/QDMA 所需的包含文件。 *
    /*------------------ *
    #include "edma_utils_autoincrement.h"
    #include "edma_utils_context_size.h"
    #include "edma_utils.h"
    #include "edma_utils_state.h"

    #include "ev_algo dma_auto_incr_Transpose.h"

    #pragma DATA_SECTION (autoIncrementContext、".edmaUtilsMem");
    静态无符号字符自动递增 Context[EDMA_utils_AUTOINCREMENT_Context_SIZE];

    int EVELIB_algoDMAAutoIncrInitSrcTranspose (
    unsigned char * src、
    unsigned int srcImageWidth、
    unsigned int srcImageHeight、
    内部 srcImagePitch、

    unsigned char *srcBlk、
    unsigned int srcBlkWidth、
    unsigned int srcBlkHeight、
    内部 srcBlkPitch、

    INTN、

    unsigned char *dst,
    unsigned int dstImageWidth、
    unsigned int dstImageHeight、
    内部 dstImagePitch、

    unsigned char *dstBlk、
    unsigned int dstBlkWidth、
    unsigned int dstBlkHeight、
    内部 dstBlkPitch)

    EDMA_utils_autoIncrement_initParam initParam;
    int32_t status = 0;

    /*重置全局状态结构*/
    //edma_utils_globalResetExtY();
    EDMA_utils_globalReset();

    VCOP_SET_MEM_VIEW (ALIAS_128K_VIEW);
    VCOP_BUF_SWITCH_SET (WBUF_SYST、IBUFHB_SYST、IBUFLB_SYST、IBUFHA_SYST、IBUFLA_SYST);

    /*vcop_SetView (VCOP_MEMALIASED);*/

    /*-------------------------------------- *
    /*为 EDMA 传输配置通道。 我们将使用两个通道、一个*/
    //用于输入传输,一个用于输出传输。 *
    /*-------------------------------------- *

    initParam.numInTransfers = 1;
    initParam.numOutTransfers = 1;
    initParam.transferType = EDMA_utils_transfer_INOUT;

    initParam.transferProp[0].roiWidth = srcImageWidth * N;
    initParam.transferProp[0].roiHeight = srcImageHeight;
    initParam.transferProp[0].roiOffset = 0;
    initParam.transferProp[0].blkWidth = srcBlkWidth * N;
    initParam.transferProp[0].blkHeight = srcBlkHeight;
    initParam.transferProp[0].extBlkIncrementX = srcBlkWidth * N;
    initParam.transferProp[0].extBlkIncrementY = srcBlkHeight;
    initParam.transferProp[0].intBlkIncrementX = 0;
    initParam.transferProp[0].intBlkIncrementY = 0;
    initParam.transferProp[0].extMemPtrStride = srcImagePitch * N;
    initParam.transferProp[0].interMemPtrStride = srcBlkPitch * N;
    initParam.transferProp[0].extMemPtr = src;
    initParam.transferProp[0]。interMemPtr = srcBlk;
    initParam.transferProp[0].dmaQueNo = 0;


    initParam.transferProp[1].roiWidth = dstImageWidth * N;
    initParam.transferProp[1].roiHeight = dstImageHeight;
    initParam.transferProp[1].roiOffset = 0;
    initParam.transferProp[1].blkWidth = dstBlkWidth * N;
    initParam.transferProp[1].blkHeight = dstBlkHeight;
    initParam.transferProp[1].extBlkIncrementX = 0;//dstBlkWidth * N;
    initParam.transferProp[1].extBlkIncrementY = 0;//dstBlkHeight;
    initParam.transferProp[1].intBlkIncrementX = 0;
    initParam.transferProp[1].intBlkIncrementY = 0;
    initParam.transferProp[1].extMemPtrStride = dstImagePitch * N;
    initParam.transferProp[1].interMemPtrStride = dstBlkPitch * N;
    initParam.transferProp[1].extMemPtr = dst;
    initParam.transferProp[1].interMemPtr = dstBlk;
    initParam.transferProp[1].dmaQueNo = 0;

    status = edma_utils_autocumine_init (autoIncrementContext、&initParam);

    如果(status =0)

    status = EDMA_utils_autoIncrement_configure (autoIncrementContext、EDMA_utils_transfer_INOUT);


    退货状态;



    void EVELIB_algoDMAAutoIncrProcessSrcTranspose
    (
    EVELIB_KernelFuncTypeTranspose execFunc[]、
    EVELIB_KernelContextTypeTranspose context[]、
    unsigned int 号码通道,

    unsigned int Vblock、
    unsigned int HBlock、

    unsigned int 块宽度、
    unsigned int BlockHeight、

    INTN、

    unsigned char *dst,
    unsigned int DstPitch
    )

    unsigned int 标记;
    内部 SinkStatus = 0;
    内部 K、RowCount、ColumnCount;

    unsigned intFirstBlock = 0;
    unsigned intPrevAddr = 0;


    EDMA_utils_aut递增_updateParams updateParams;

    VCOP_BUF_SWITCH_SET (WBUF_SYST、IBUFHB_SYST、IBUFLB_SYST、IBUFHA_SYST、IBUFLA_SYST);

    /*-------------------------------------- *
    /*处理循环从此处开始 *
    /*-------------------------------------- *
    flag = BUF_ping;
    VCOP_BUF_SWITCH_SET (WBUF_VCOP、IBUFHB_VCOP、IBUFLB_VCOP、IBUFHA_SYST、IBUFLA_SYST);


    /*------------------------------------ *
    /*序言: *
    /*获取第一个块 *
    /*------------------------------------ *
    EDMA_utils_autocincrement_triggerInChannel (autobincreinmentContext);
    EDMA_utils_autocumine_waitInChannel (autoIncrementContext);

    updateParams.transferType = EDMA_utils_transfer_out;
    updateParams.updateMask = EDMA_utils_AUTOINCREMENT_UPDATE_MASK_EXTMEMPTTR;

    对于(RowCount = 0;RowCount < HBlock;RowCount++)

    对于(ColumnCount = 0;ColumnCount < Vblock;ColumnCount++)


    标志= VCOP_BUF_SWITCH_TOGGLE (标志);

    if (FirstBlock){
    //updateParams.updateParams[0].extMemPtr =(uint8_t*)(dst +(ColumnCount * blockWidth * DstPitch)+(RowCount * blockHeight));
    updateParams.updateParams[0].extMemPtr =(uint8_t*)(dst + PrevAddr);

    //edma_utils_autoIncrement_update (autoIncrementContext、&updateParams);

    /* Rachit Fix:在输出通道触发时、在每次迭代中更新外部存储器地址
    *
    * blkHorzIdxOut = 0、更新外部存储器指针
    *
    * blkVertIdxOut = 0、更新 extPtrOffset = 0
    *
    ***/
    自动递增 Context[24]=0;
    自动递增 Context[25]=0;

    SINKStatus = EDMA_UTILS_aut增量 触发器 OutChannel (自动增量控制);

    PrevAddr =(ColumnCount * blockWidth * DstPitch * N)+(RowCount * N * blockHeight);


    FirstBlock = 1;

    EDMA_utils_autocincrement_triggerInChannel (autobincreinmentContext);

    /*---------------------- *
    /*将其余内核提交给 VCOP */
    /*---------------------- *
    对于(k=0;<numKernels; k++) 0.0.8

    (cexecFunc[k])(context[k]);


    /*------------------------------------ *
    /*检查第一个水平块是否完成 *
    /*进入内部循环之前。 *
    /*------------------------------------ *
    EDMA_utils_autocumple_waitOutChannel (autoIncrementContext);
    EDMA_utils_autocumine_waitInChannel (autoIncrementContext);

    /*---------------- *
    /*等待 VCOP 完成*/
    /*---------------- *
    _vcop_vloop_done ();



    /*----------------- *
    /*结束语: *
    /*传输行中最后处理的块 *
    /*-------------------------------------- *
    标志= VCOP_BUF_SWITCH_TOGGLE (标志);

    updateParams.updateParams[0].extMemPtr =(uint8_t*)(dst + PrevAddr);

    EDMA_utils_autoIncrement_update (autoIncrementContext、updateParams);

    自动递增 Context[24]=0;
    自动递增 Context[25]=0;

    SINKStatus = EDMA_UTILS_aut增量 触发器 OutChannel (自动增量控制);
    EDMA_utils_autocumple_waitOutChannel (autoIncrementContext);

    /*----------------- *
    /*在返回之前将所有缓冲区返回到系统。 *
    /*----------------- *
    VCOP_BUF_SWITCH_SET (WBUF_SYST、IBUFHB_SYST、IBUFLB_SYST、IBUFHA_SYST、IBUFLA_SYST);


    void EVELIB_algoDMAAutoIncrDeInitTranspose ()

    EDMA_utils_globalReset();
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    我正在寻找 DMA 寄存器的配置。 您能告诉我您使用的块尺寸是多少?

    此致、
    安州
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    块宽度= 64
    块高度= 48
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    为什么在每个循环后更新内存指针? 由于更新 API 具有多种条件检查、因此每帧只能使用一次更新 API。 您能否向我解释一下您的数据流以及为何需要此更新?

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

    因为我们必须垂直存储水平转置块。

    请您参考我之前的帖子、其中我提到了自动递增用例时间的分析。

    初始化时间(内核和 DMA 数据传输禁用)为~275 μ s、也有更新 API 时间。 因此、更新 API 不会增加执行时间。

    此致、
    Prashant Kothari
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    我认为这不是使用 DMA 的正确方法。 我看到您将 EDMA 上下文的某些值设置为零、这也不是使用 API 的正确方法、因为您正在修改用户不会修改的内部上下文。 我很难评论 DMA 为什么要花费额外的时间、因为我不确定描述代码中到底包含了什么内容。 您可以看到的一件事是、是否有任何 DMA 上下文或堆栈位于 DDR 中而不是 DMEM 中。 这会导致性能下降。
    我确实看到 EDMA API 使用不当、因此让我们首先了解您的需求、然后我们可以建议如何高效地实现这一目标。
    我将列出我迄今为止了解的数据流。 让我知道在理解上是否有任何差距:
    输入图像640 x 480
    2.输入块大小= 64 x 48
    3.输出块大小= 48 x64 (假设正在执行的操作已转置)
    4.输出图像大小= 480 x 640 (假设您所执行的操作已转置)
    根据我的理解、您首先需要将64x48块水平转置并垂直写入输出块。 对于此数据流、不建议使用自动测量 API、但如果您的垂直跳转在16位有符号数内(这对于当前480 x 640的配置是正确的、因为跳转将是480 * 64)、则仍可以使用。 因此、如果映像大小是固定的、则可以通过正确设置 extBlkIncrementX 和 extBlkIncrementY 来使用上述 API。 如果是输出通道、则应 extBlkIncrementX = 480 * 64且 extBlkIncrementY = 48。 在处理过程中、需要使用此用户更新。 但是、如果您的图像尺寸较大、这种情况可能并不总是正确的。 在这些情况下、您应该使用散聚 EDMA 实用程序、在该实用程序中、您可以更新每个块级别的指针、这样会更加高效。

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

    您对我们希望通过 DMA 传输的数据流是正确的。
    我们希望使 API 可配置、以便映像大小可以是任意值。
    块大小也可能因图像大小而异。 我们的图像尺寸可高达1280 X 960至160 X 120。
    在初始化时、我们已注释内核调用函数+ dma_submit ()& dma_wait()调用。
    因此、这是 EVE 的基准时间、它不会对 VCOP 进行任何处理、也不会在 DMA 上进行数据传输、这大约为275us、持续100个块。

    在输入和输出传输中使用相同的自动上下文、在这两种情况下、我们应该具有相同数量的水平块和垂直块。
    但这并不总是能够转置图像。 更改过程中的自动上下文可以变通、以便为输入和输出使用相同的自动上下文。

    在自动上下文中,我们基本上设置 autocincrementHandle->blkHorzIdxOut = 0,这将帮助我们每次更新指针。

    主要问题是关于 eve 版本。 最初、我们使用 Vision SDK 2.7进行开发、开发过程中的时间更长、但使用 Vision SDK 2.12时、时间接近估算值。

    其次、我们已经尝试了散聚 EDMA 实用程序、我们的时间接近预期(~1 msec)。

    非常感谢您的支持。

    此致、
    Prashant Kothari
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    很高兴听到您的计时问题得到解决。 我要强调的一点是、您可以为输入和输出通道使用两种不同的上下文、其中一个配置输入、另一个仅配置输出(在本例中请记住使 numInTransfer = 0)。 这样、输入和输出通道的水平和垂直块数量将不受限制。
    但是、当您希望它与可配置的尺寸配合使用时、最好在这种情况下使用散聚 DMA utils、因此输入和输出通道将具有不同的上下文。

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

    为此、我们尝试了不同的输入和输出上下文、但我们没有得到明显的计时差异。

    如上一帖子中所述、我们在 VISION_SDK 12.0中集成了自动增量用例、并接近估算时间。

    其次、我们还在 VISION_SDK 12.0中集成了散聚模式变化、执行时间与 VISION_SDK 2.7相同。

    那么、是否有针对自动递增的 DMA 库优化用例 VISION_SDK 12.0?

    此致、
    Prashant Kothari
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Prashant、
    这两种上下文解决方案并不是为了提高性能、而是主要是为了清晰地使用 DMA utils (避免接触实用程序的内部上下文)。
    可能已经有一些改进、会提高性能、但我无法通过引脚指出这些版本已经发生了哪些变化、因为这些版本已经很旧了。

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

    感谢您的支持。