【问题标题】:FPGA - CPU Latency measurement with C/C++FPGA - 使用 C/C++ 进行 CPU 延迟测量
【发布时间】:2017-06-15 11:35:54
【问题描述】:

我正在尝试测量同一板上的 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-*-*-*

【问题讨论】:

  • 嵌入式系统使用示波器进行基准测试。这就是为什么没有一个你就不能进行任何形式的嵌入式系统编程。
  • 数字信号示波器(或工程界的 DSO)是一个非常昂贵的单元。体面的逻辑分析仪(我是 Saleae 的粉丝)非常适合。
  • 如果你正在设计一个 fpga 板,你有一个范围,如果这是一个现成的,那就是另一回事了。
  • 如果您在使用中遇到中断,请不要忘记在实际测量时禁用它们,即在获取第一次时间戳之前,并在获取第二次之后再次启用它们-戳!

标签: c++ c timer arm fpga


【解决方案1】:

根据所涉及的时间跨度(毫秒、微秒、纳秒),您可能会在 readTimer 调用中丢失粒度。更准确的方法是使用硬件探头和示波器。在进入 writeToFPGA 例程时将测试点设置为高,在退出时设置为低。较新的示波器可以为您平均脉冲宽度,但即使您没有该功能,您也会看到绝对时间并感受可变性。

【讨论】:

    【解决方案2】:

    将您的算法更改为这样以获得更高的精度,

    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 端进行一些调查以改善访问。

    【讨论】:

    • 使用作用域时,尝试找到一个信号,使事务完成。例如,如果是 AHB 总线,您可以尝试 HCLKHREADY。使用示波器可能很复杂,因为并非每个人都有能够捕获信号的示波器和/或总线可能无法提供良好的触发信息。如果您可以将任意数据写入 FPGA,您可以使用它来帮助触发示波器。
    【解决方案3】:

    无论 readTimer() 调用是如何实现的(可能是简单的本地外围设备读取),您的基准测试都是在将关键写入与其他处理交错时编写的。根据内核的不同,这可能会显示一个周期(对于 STR)。当循环再次出现时,STR 可能已经完成。

    您的基准不太可能代表您要解决的实际问题。即使您在循环中重复 STR 1000 次,您仍然没有观察到实际延迟,您现在正在查看流向 FPGA 的带宽,这是可能的。

    根据系统的不同,延迟意味着内核可以多快(从确定的事件)触发 FPGA 中的响应。传统上,这可能是 IRQ,将一些数据传递给 FPGA,返回响应,写入外围设备(除非是 FPGA 驱动引脚)。

    更好的方法可能是将数据写入 FPGA,读回 FPGA 寄存器(易失性,设备区域),使用数据,然后将其放入循环中。

    根据设备内存系统的不同,这仍然可能不会给出与系统性能相关的结果(例如,Cortex-R8、Cortex-M0 将在非常不同的系统中)。

    【讨论】:

      【解决方案4】:

      我倾向于向 FPGA 添加性能测量,而不是使用外部示波器或逻辑分析仪。这样,我可以测量处理来自 CPU 的请求的总周期数和平均周期数,还可以通过执行背靠背请求和测量总经过周期来测量 CPU 开销。我也经常测量双向传输的数据量。

      【讨论】:

        猜你喜欢
        • 2015-01-23
        • 2013-02-17
        • 2020-10-26
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 2014-02-16
        • 2011-07-22
        • 1970-01-01
        相关资源
        最近更新 更多