我们的任务旨在证明使用DMA复制大量数据与依靠处理器直接处理复制相比的好处。 处理器是ST发现板上的STM32F407。
为了测量复制时间,必须在复制过程中将GPIO引脚置为ON,并在复制后将其关闭。
该代码似乎可以正常运行,但是当前显示的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);
}
在此先感谢您的帮助
答案 0 :(得分:7)
您尝试证明不正确的东西。 DMA内存到内存的传输总是比直接CPU慢。 DMA的意图不是要比CPU快。它是提供转移w 在后台没有CPU 活动。内核始终优先于DMA。
从MEM到MEM的DMA传输总是比CPU慢
还有另一个问题。许多STM设备具有DMA无法访问的存储区(例如CCMRAM)。
答案 1 :(得分: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
您先打开图钉,然后打印大文本,这将合计您的总时间。
删除所有printf
或至少在引脚切换之间不打印任何内容。
编辑:
准确地说,如果要传输 DMA ,则要打印 50 个字符,如果要 CPU 23 个字符>转移。
答案 2 :(得分:-1)
对于那些谁在谷歌搜索“如何加快DMA内存到内存的传输?”的人这是一条建议:强制编译器将所有与DMA传输相关的HAL代码分配给RAM,最好是分配给专门与Core耦合的RAM。您的编译器将生成功能代码,该功能代码将在启动时复制到特定的RAM中,然后所有这些功能将从RAM中调用并因此而加速。但是,“手动”复制也是如此。 在这种情况下,建议将以下文件/功能分配给RAM: