如何测量DMA 的传输速度呢
时间: 2024-02-24 19:54:35 浏览: 162
要测量DMA传输速度,可以使用Xilinx提供的性能计数器功能来计算传输的数据量和传输所需的时间。以下是一个示例代码,展示如何使用性能计数器来测量DMA传输的速度:
```c
#include <stdio.h>
#include <stdlib.h>
#include "xaxidma.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xtmrctr_l.h"
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#define BUFFER_SIZE 1024
#define TIMER_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
#define TIMER_COUNTER_0 0
u32 ReadTimerCounter(XTmrCtr *TmrCtrInstance, u8 TmrCtrNumber)
{
u32 Value;
Value = XTmrCtr_GetValue(TmrCtrInstance, TmrCtrNumber);
return Value;
}
int main()
{
XAxiDma AxiDma;
XAxiDma_Config *CfgPtr;
int Status;
int i;
int *TxBufferPtr;
int *RxBufferPtr;
int Value;
int Error = 0;
int TestLength = BUFFER_SIZE * sizeof(int);
XTmrCtr TimerCounterInst;
u32 TimerCounterValue;
TxBufferPtr = (int *)malloc(BUFFER_SIZE * sizeof(int));
RxBufferPtr = (int *)malloc(BUFFER_SIZE * sizeof(int));
for (i = 0; i < BUFFER_SIZE; i++) {
TxBufferPtr[i] = i;
}
CfgPtr = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!CfgPtr) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}
if(!XAxiDma_HasSg(&AxiDma)) {
xil_printf("Device configured as simple mode \r\n");
return XST_FAILURE;
}
Status = XAxiDma_Selftest(&AxiDma);
if (Status != XST_SUCCESS) {
xil_printf("Self test failed %d\r\n", Status);
return XST_FAILURE;
}
XAxiDma_Reset(&AxiDma);
while (XAxiDma_ResetIsDone(&AxiDma) != 1);
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);
XTmrCtr_Initialize(&TimerCounterInst, TIMER_DEVICE_ID);
XTmrCtr_SetOptions(&TimerCounterInst, TIMER_COUNTER_0, XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION);
XTmrCtr_Start(&TimerCounterInst, TIMER_COUNTER_0);
Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)RxBufferPtr, TestLength, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
xil_printf("RX transfer failed %d\r\n", Status);
return XST_FAILURE;
}
Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)TxBufferPtr, TestLength, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {
xil_printf("TX transfer failed %d\r\n", Status);
return XST_FAILURE;
}
while (XAxiDma_Busy(&AxiDma, XAXIDMA_DEVICE_TO_DMA));
TimerCounterValue = ReadTimerCounter(&TimerCounterInst, TIMER_COUNTER_0);
for (i = 0; i < BUFFER_SIZE; i++) {
Value = RxBufferPtr[i];
if (Value != i) {
xil_printf("Data error %d: %d/%d\r\n", i, Value, i);
Error ++;
}
}
if (Error) {
xil_printf("Test failed %d/%d\r\n", Error, BUFFER_SIZE);
return XST_FAILURE;
} else {
xil_printf("Test passed %d/%d\r\n", BUFFER_SIZE - Error, BUFFER_SIZE);
}
xil_printf("Transfer time: %d cycles\r\n", TimerCounterValue);
xil_printf("Transfer speed: %d MB/s\r\n", (BUFFER_SIZE * sizeof(int)) / (1024 * 1024 * (TimerCounterValue / (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 1000000))));
return XST_SUCCESS;
}
```
在上述代码中,我们添加了一个计时器,使用该计时器来测量DMA传输所需的时间。在传输完成后,我们计算传输速度。具体地,我们使用以下公式来计算传输速度:
传输速度 = 传输的字节数 / (计时器值 / (CPU时钟频率 / 1000000))
其中,CPU时钟频率是指CPU的时钟频率,以赫兹为单位。计时器值是在传输期间读取的计时器值,以CPU时钟周期为单位。传输的字节数是指传输的数据量,以字节为单位。
通过测量DMA传输速度,可以帮助我们优化DMA传输的性能,以满足应用程序的要求。
阅读全文