【问题标题】:mmap, axi and multiple reads from pciemmap、axi 和来自 pcie 的多次读取
【发布时间】:2020-07-30 17:59:12
【问题描述】:

我正在尝试通过 mmap 优化通过 pcie 读取数据。当时我们有一些工具允许从 PCIe 通信中读取/写入一个单词,但我想在一个请求中获取/写入尽可能多的单词。

我的项目使用 PCIe Gen3 和 AXI 桥接器(2 个 PCIe 条)。

我可以从总线上成功读取任何单词,但在请求数据时我注意到了一种模式:

  • 在地址0请求数据:AXI master请求4个地址的数据,初始地址为0
  • 请求地址0和1的数据:两个AXI请求:第一个和上面类似,后面是3个地址数据的读请求,初始addr为1
  • 从地址0到2请求数据:3个AXI请求:前两个和前一个类似,后面是2个地址数据的读请求,初始addr为2

该模式一直持续到 addr 是 4 的倍数。似乎如果我请求第一个地址,AXI 会发送前 4 个值。有什么提示吗?这可能在我正在使用的驱动程序上吗?

这是我使用 mmap 的方法:

        length_offset = tmp_offset_rw & ~(sysconf (_SC_PAGESIZE)-1);
    mmap_offset = (u_long)(tmp_barx_rw << 12) + length_offset;
    mmap_len = (u_long)(tmp_size * sizeof(int));
    mmap_address = mmap(NULL, mmap_len + (int)(tmp_offset_rw) - length_offset,
            PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_offset);

    close(fd);
    // tmp_reg_buf = new u_int[tmp_size];
    // memcpy(tmp_reg_buf, mmap_address , tmp_size*sizeof(int));
  
    // for(int i = 0; i < 4; i++)
    //   printf("0x%08X\n", tmp_reg_buf[i]);
    
    for(int i = 0; i < tmp_size; i++)
      printf("0x%08X\n", *((u_int*)mmap_address + (int)tmp_offset_rw - length_offset + i));

【问题讨论】:

  • 我不明白问题的措辞。在每种情况下,您要读取多少字节,地址的对齐方式是什么?请发布一些您用于从内存映射区域读取的代码。
  • 感谢您的回复。我想说的是,我想通过一个请求从 PCIe 内存中读取多个整数。看来内核只支持单个读/写转换可能是这种情况吗?即使很难,它也清楚地发送了 4 的倍数的数据请求。
  • 您的代码明确表示一次读取 4 个字节,那么您为什么会期待不同的内容呢?您是否尝试过使用读取超过 4 个字节的指令?
  • 您描述的行为听起来像 memcpy 的行为(您已在示例代码中注释掉)。 Memcpy 被定义为执行字节访问,并不真正适合访问 MMIO。如果您的描述与您的代码匹配,则更容易回答您的问题。
  • 内核不参与这些访问。这只是您的软件和硬件。

标签: fpga mmap pci-e


【解决方案1】:

首先,驱动只是建立应用虚拟地址和物理地址的映射关系,并不参与CPU和FPGA之间的请求。

PCIe 内存区域通常以非缓存方式映射,因此您在 FPGA 中看到的内存请求与 CPU 正在读取或写入的值的宽度完全对应。

如果您反汇编您编写的代码,您将看到加载和存储指令在不同宽度的数据上运行。根据 CPU 架构,请求更宽数据宽度的加载/存储指令可能有地址对齐限制,或者可能会因获取未对齐的数据而导致性能下降。

不同的memcpy() 实现通常有特殊情况,因此它们可以使用尽可能少的指令来传输一定数量的数据。

memcpy() 可能不适合 MMIO 的原因是,memcpy() 可能会读取比指定更多的内存位置,以便使用更大的传输大小。如果 MMIO 内存位置对读取造成副作用,则可能会导致问题。如果你要暴露一些行为类似于内存的东西,可以将 memcpy() 与 MMIO 一起使用。

如果您想要更高的性能并且在 PCIe 的主机端有可用的 DMA 引擎,或者您可以在 FPGA 中包含一个 DMA 引擎,那么您可以安排传输达到 PCIe 协议、BIOS、以及 FPGA 上 PCIe 端点的配置。 DMA 是最大化吞吐量的方法,通常可以使用 128 或 256 字节的突发。

为了最大限度地提高吞吐量,需要解决的下一个问题是延迟,它可能会很长。 DMA 引擎需要能够对请求进行流水线处理,以屏蔽从 FPGA 到内存系统并返回的延迟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多