DMA传输比CPU传输花费更多的时间

Joe*_*e P 4 c stm32 memcpy dma

我们的任务旨在证明使用DMA复制大量数据与依靠处理器直接处理复制相比的好处。处理器是ST发现板上的STM32F407。

为了测量复制时间,必须在复制期间将GPIO引脚打开,并在复制后将其关闭。

该代码似乎是功能性,但它当前示出了CPU服用约2.15ms至完整和DMA约4.5ms,这是何意相反。我不确定是否没有足够的数据来提供更快的DMA速度来抵消设置数据的开销?

我尝试使用CPU和memcpy函数复制数组的元素,这似乎产生非常相似的时间。

功能代码如下所示:

DMASpeed(void)
{
    #define elementNum 32000
    int *ptr = NULL;
    ptr = (int*)malloc(elementNum * sizeof(int));
    int *ptr2 = NULL;
    ptr2 = (int*)malloc(elementNum * sizeof(int));
    for (int i = 0; i < elementNum; i++)
    {
        ptr[i] = 4;
    }
    LD5_GPIO_Port->BSRR = (uint32_t)LD5_Pin << 16U;
    LD6_GPIO_Port->BSRR = (uint32_t)LD6_Pin << 16U;
    // Initial value
    // printf("BEFORE: dst = '%s'\n", dst);

    // Transfer
    printf("Initiate DMA Transfer...\n");
    HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (int)ptr, (int)ptr2, (elementNum * sizeof(int)));
    LD5_GPIO_Port->BSRR = LD5_Pin;
    printf("DMA Transfer initiated.\n");


    // Poll for DMA completion
    printf("Poll for DMA completion.\n");
    HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0,
        HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
    LD5_GPIO_Port->BSRR = (uint32_t)LD5_Pin << 16U;
    printf("DMA complete.\n");

    // Print result
    // printf("AFTER: dst = '%s'\n", dst);
    free(ptr);
    free(ptr2);

    ptr = (int*)malloc(elementNum * sizeof(int));
    ptr2 = (int*)malloc(elementNum * sizeof(int));
    for (int i = 0; i < elementNum; i++)
    {
        ptr[i] = i;
    }

    printf("Initiate CPU Transfer...\n");
    LD6_GPIO_Port->BSRR = LD6_Pin;
    //  for (int i = 0; i<512; i++)
    //  {
    //  ptr2[i] = ptr[i];
    //  }
    memcpy(ptr2, ptr, (elementNum * sizeof(int)));
    printf("CPU Transfer Complete.\n");
    LD6_GPIO_Port->BSRR = (uint32_t)LD6_Pin << 16U;

    free(ptr);
    free(ptr2);
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的协助

P__*_*J__ 7

您尝试证明不正确的东西。DMA内存到内存的传输总是比直接CPU慢。DMA的意图不是要比CPU快。它可以在没有CPU活动的情况下提供传输w 。内核始终优先于DMA。

MEM到MEM的DMA传输总是比CPU

还有另一个问题。许多STM设备具有DMA无法访问的存储区(例如CCMRAM)。


Vag*_*ish 5

printf在下面的代码段中删除:

LD5_GPIO_Port->BSRR = LD5_Pin;
printf("DMA Transfer initiated.\n");  // <--Remove this


// Poll for DMA completion
printf("Poll for DMA completion.\n"); // <--Remove this
Run Code Online (Sandbox Code Playgroud)

您打开引脚,然后打印大文本,这将合计您的总时间。

删除所有printf 或至少在引脚切换之间不打印任何内容。

编辑

准确地说,在DMA传输的情况下,您要打印50个字符,在CPU传输的情况下,您要打印23个字符。