我正在尝试测量同一电路板中ARM CPU和FPGA之间的读/写延迟。我想知道使用全局定时器是否足以在时钟周期内报告这种延迟,因为ARM和FPGA以不同的频率运行。 我的方案是
resetTimer();
startTimer();
for(i=0; i<1000; i++) {
T1 = readTimer();
writeToFpgaIP(int* regAddress, int data);
T2 = readTimer();
storeInArray(T2-T1);
}
StopTimer();
latency = sum (array_write_timing[]) / 1000;
-*-*-*-End algo-*-*-*
答案 0 :(得分:3)
根据所涉及的时间跨度(毫秒,微秒,纳秒),您可能会在readTimer调用中丢失粒度。更准确的方法是使用硬件探针和示波器。在进入writeToFPGA例程时将测试点设置为高,在退出时设置为低。较新的示波器可以为您平均脉冲宽度,但即使您没有这种能力,您也会看到绝对时间并感受到可变性。
答案 1 :(得分:3)
将算法更改为更精确,
resetTimer();
startTimer();
T1 = readTimer();
for(i=0; i<1000; i++) {
writeToFpgaIP(int* regAddress, int data);
}
T2 = readTimer();
StopTimer();
latency = (T1-T2) / 1000;
您可以尝试通过创建另一个模仿现有循环并为其计时的循环来测量循环开销。例如,如果writeToFpgaIP
是函数,
dummyCall(int* regAddress, int data){}
dummyWrite(int* regAddress, int data){volatile int foo = data;}
dummyCall
只是看编译器函数调用开销,dummyWrite
是比较FPGA总线与核心内存(或缓存)。
检查汇编程序以确保编译器没有优化的东西,并仔细检查它是否类似于基准循环。您可能不得不使用编译器选项,以便dummyCall
(或dummyWrite
)的循环结构与writeToFpgaIP
类似。
使用示波器是有益的,但它只能测量FPGA端的时序。您无法确定数据在到达CPU / SOC引脚后会发生什么情况。所以使用这两种技术可能是有益的;确保他们互相确认。
如果没有,那么连接FPGA的端口/总线可能需要在ARM端进行一些调查以改善访问。
答案 2 :(得分:0)
无论readTimer()调用是如何实现的(可能是简单的本地外设读取),您的基准测试都是将您的关键写入与其他处理交错编写的。根据核心,这可能会显示一个周期(对于STR)。当循环再次出现时,STR可能已经完成。
您的基准测试不太可能代表您尝试解决的实际问题。即使你在一个循环中重复STR 1000次,你仍然没有观察到实际的延迟,你现在正在查看FPGA的流带宽。
根据系统的不同,延迟意味着核心可以在FPGA中触发响应的速度(来自确定的事件)。传统上,这可能是IRQ,将一些数据传递给FPGA,返回响应,写入外设(除非它是FPGA驱动引脚)。
稍微好一点的方法可能是将数据写入FPGA,读回FPGA寄存器(易失性,器件区域),使用数据,并将其置于循环中。
根据设备内存系统的不同,这仍然可能无法提供与系统性能相关的结果(例如,Cortex-R8,Cortex-M0将在非常不同的系统中)。
答案 3 :(得分:0)
我倾向于将性能测量添加到FPGA中,而不是使用外部示波器或逻辑分析仪。这样,我可以测量处理来自CPU的请求的总循环次数和平均循环次数,我还可以通过执行背对背请求和测量总经过的周期来测量CPU开销。我经常也测量向任一方向传输的数据量。