Передача DMA занимает больше времени, чем передача процессора - PullRequest
4 голосов
/ 14 мая 2019

Наша задача - продемонстрировать преимущества использования DMA для копирования большого объема данных по сравнению с использованием процессора для непосредственной обработки копирования.Процессор представляет собой STM32F407 на плате обнаружения ST.

Чтобы измерить время копирования, пин-код GPIO должен быть включен во время копирования и выключен после того, как он скопирован.

Код, кажется, работает, но в настоящее время показывает процессортребуется около 2,15 мс для завершения и DMA около 4,5 мс , что противоположно тому, что предполагалось.Я не уверен, что просто недостаточно данных для более быстрой скорости DMA, чтобы компенсировать накладные расходы при его настройке, возможно?

Я пробовал как копировать элементы массива, используя ЦП, так и используяфункция 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);
}

Заранее благодарим за любую помощь

Ответы [ 2 ]

7 голосов
/ 14 мая 2019

вы пытаетесь доказать что-то, что не является правдой. Передача памяти DMA в память всегда будет медленнее, чем прямая загрузка процессора. DMA не должен был работать быстрее, чем процессор. это там, чтобы обеспечить передачу ж без процессора активность в фоновом режиме. ядро всегда имеет приоритет над DMA.

Передача MEM в MEM DMA будет всегда медленнее , чем ЦП

Есть и другая проблема. Многие устройства STM имеют области памяти, которые недоступны DMA (например, CCMRAM).

5 голосов
/ 14 мая 2019

Удалить 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 ИЛИ, по крайней мере, ничего не печатать между переключениями выводов.

РЕДАКТИРОВАТЬ :

Если быть точным, вы печатаете 50 символов в случае DMA передачи и 23 символов в случае CPU передачи.

...