用Xilinx XDMA做PCIe Gen3 x8数据采集,主机端测DMA读带宽只有2GB/s左右。已经开了多个H2C/C2H通道,MPS和MRRS也调过。想问问有经验的前辈,这种带宽上不去一般先查哪里?是TLP包大小、DDR控制器效率,还是主机内存拷贝?
2026年FPGA工程师做PCIe DMA,理论带宽8GB/s实测只有2GB/s,瓶颈到底在TLP还是DDR?
5 个回答

先别急着怀疑 DDR,Gen3 x8 理论也就 8GB/s 左右,实际能到 5~6 就算不错了。用 ILA 抓一下 TLP 长度和 AXI 突发,如果全是 64B/128B 的小包,那瓶颈基本就在 TLP 侧。你的 MPS/MRRS 是两端都对齐了吗?

先别急着怀疑 DDR,Gen3 x8 理论也就 8GB/s 左右,实际能到 5~6 就算不错了。用 ILA 抓一下 TLP 长度和 AXI 突发,如果全是 64B/128B 的小包,那瓶颈基本就在 TLP 侧。你的 MPS/MRRS 是两端都对齐了吗?

我去年陪朋友调过一块类似的采集卡,他一开始也以为是 DDR 效率低,折腾了两周才发现根子在主机侧。先说排查顺序:拿一个纯读或纯写的单向测试跑一遍,别一上来就双向同时压,双向会把读写切换开销叠进来,数字看着更惨。然后分三段量:主机端 memcpy 到用户缓冲的耗时、XDMA 驱动里描述符提交到完成的耗时、FPGA 侧 AXI 上实际搬的字节数除以时间。哪一段掉得最狠就往哪查。
TLP 侧最常见的坑是跨 4KB 边界。主机内存是分页的,一个 TLP 如果跨了 4KB 边界,很多根复合体会把它拆成两个甚至更多小包,MRRS 设得再大也白搭。所以看 ILA 的时候不光看长度,还要看地址低位,如果大量 TLP 落在 4KB 边界附近被切断,那就是描述符切分策略的问题。另一个是 C2H 通道的 descriptor 环深度不够,FPGA 侧来不及补描述符,DMA 引擎空转,这种在 ILA 上表现为突发之间有大段空闲。
DDR 这边,如果 AXI 突发长度是 256 拍、位宽 512bit,理论效率不难看,但要注意读写交替时的 tWTR/tRTW 惩罚,以及刷新带来的周期性掉速。可以用 AXI Performance Monitor 或者自己插计数器统计有效字节占比,低于 70% 就值得看 bank 冲突和调度了。
个人建议先固定一个变量:把 DDR 换成纯 BRAM 或 FIFO 回环,如果带宽还是 2GB/s,那 DDR 直接洗清嫌疑,火力全集中到 TLP 和主机侧。你现在是单向测试还是双向同时跑的?

其实最快的判断办法是做个减法。把 FPGA 侧的数据源换成内部递增计数器,完全不碰 DDR,主机端只收不存,看带宽能到多少。如果这时候还是 2GB/s,那 DDR 是冤枉的,问题在 TLP 打包或主机接收路径;如果能冲到 5GB/s 以上,再回头查 DDR 的读写调度和跨时钟域 FIFO 有没有反压。
主机侧也别忽略,很多采集程序用一次 malloc 出来的大缓冲,页没锁住,DMA 过程中被换出或者走的是 bounce buffer,带宽直接砍半。先用大页或者 mlock 锁住内存再测一遍,成本很低。

先给一个我自己的排查顺序,基本是按「改起来便宜、见效快」排的,不一定严格按物理链路顺序。因为时间有限,别一上来就去啃 DDR 控制器,那玩意儿改起来最慢、坑最深。
第一步先量主机内存带宽。找一台机器跑个 STREAM 或者 memcpy 基准,看单线程/多线程的峰值是多少。很多采集程序用的是普通 malloc 缓冲,DMA 过程中页被换出、走 bounce buffer,带宽直接砍半。用大页或者 mlock 锁住内存再测一遍,这一步成本极低,但能排除掉一大类「不是 PCIe 的锅」。
第二步查 PCIe 配置空间。MPS 和 MRRS 两端都要对齐,主机端 root complex 的 MPS 和 FPGA 端 endpoint 的 MPS 不一致时,取的是较小值。很多人只改了 FPGA 侧,忘了看 lspci -vv 里主机侧的实际值。这两个参数不对齐,TLP 的 payload 会被压小,Gen3 x8 理论 8GB/s,实际掉到 2GB/s 很常见。
第三步才是用 ILA 抓 TLP 和 AXI 突发长度。重点看两件事:一是 TLP 是不是大量落在 64B/128B 的小包区间,二是地址低位,看有没有大量 TLP 在 4KB 边界附近被切断。主机内存分页是 4KB 对齐的,一个 TLP 跨了 4KB 边界,很多根复合体会把它拆成两个甚至更多小包,MRRS 设得再大也白搭。所以描述符切分策略比单纯调 MRRS 更关键。
第四步看 XDMA 通道数。多开 H2C/C2H 通道确实能提升并发,但通道数太多会让每个通道的 descriptor 环变浅,反而增加中断和调度开销。一般做法是先把单通道跑满,确认单通道能到多少,再逐步加通道数看边际收益。如果单通道只有 500MB/s,开四个也就 2GB/s,说明瓶颈不在并发度。
最后才是 DDR。如果前面几步都正常,TLP 是大包、地址也不跨边界,再看 DDR 的读写调度。DDR 侧重点看读写切换开销和 bank 冲突,单向读写测试和双向同时压的数字差别很大。
一句话总结:先排除主机侧和 TLP 侧,DDR 放最后。你现在单通道能跑到多少?这个数字比总带宽更能说明问题。
发表回答
登录后可在本页底部提交回答