最近在做车规级激光雷达的点云处理,用Zynq UltraScale+接了两颗DDR4,点云数据量一大DDR带宽直接吃满,帧率只能降到15fps,客户不接受。想请教一下各位,除了降帧率和换DDR5这两条路,有没有人试过在FPGA里做无损或近无损压缩,比如对点云坐标和反射率做差分编码或霍夫曼编码?另外,把部分点云滤波或者体素下采样直接做到DDR控制器附近,算不算近内存计算?实际工程中这两种方案对带宽的改善能有多少?
2026年了,FPGA工程师搞车规激光雷达点云处理,DDR带宽不够用,除了降帧率和换DDR5,用数据压缩或近内存计算能解决吗?
8 个回答

先说结论:差分坐标加霍夫曼这条路,在点云场景里确实能吃到肉,但别指望它替代DDR5,更多是帮你把余量从「爆掉」变成「够用」。我去年在Xilinx的ZU+上做过类似尝试,点云坐标按体素分块后做16位差分,反射率单独做查表熵编码,压缩比大概在2.3到2.8之间浮动,帧率能从15拉回22。关键是别对全帧做统一编码,雷达点云稀疏性很强,按扫描线或按距离门分块,局部坐标差值的动态范围会小很多。另一个坑是霍夫曼在FPGA里做变长码解码很费LUT,建议只对坐标差分用固定位宽的截断编码,反射率走静态哈夫曼表,这样流水线简单。近内存滤波那块,我的经验是收益不如压缩直接,因为滤波本身也要读数据,除非你把体素下采样做到DDR控制器和AXI互联之间,用片上SRAM做累加器,写回时只写非空体素。这个对带宽的改善取决于你的点云分布,均匀分布时大概省20%写带宽,但工程复杂度会上一个台阶。建议你先拿三帧真实数据做离线统计,算清楚坐标差分后的熵值,再决定要不要上硬件。你现在的点云是16线还是64线?每帧点数大概什么量级?这个对压缩比影响挺大。

这问题我建议你先别急着选压缩还是近内存,先花两天把数据特征摸清楚。你现在的瓶颈到底是读带宽还是写带宽?很多人在Zynq上跑点云,实际是被反复搬运的中间结果吃掉的,比如你做了体素滤波又要做地面分割,中间每一级都从DDR读一遍写一遍,这时候加压缩反而会增加延迟,不如把两级处理合并成单次遍历。我们之前做过一个项目,最初也是DDR带宽打满,后来发现是坐标转换模块把原始点云读了三次,改成流水线里直接传递经过量化的中间坐标,带宽立刻降了30%,根本没碰压缩。如果确认是原始数据量本身太大,那无损差分编码是首选,但要注意车规场景里点云坐标经常有跳变,比如远距离点稀疏,差分值会突然变大,这时候定长编码反而比霍夫曼稳,因为最坏情况可控。近内存计算这个词在学术圈被用滥了,实际工程里更值得做的是把点云按扫描线切块,让每个处理单元只访问自己那块的DDR burst,别让多个模块交叉读写同一片地址,这比在控制器旁边加滤波器更实用。至于压缩比,别信论文里的3:1,车规雷达的反射率噪声大,熵编码效果很不稳定,我见过最差的情况压缩比只有1.4。你最好抓三组典型场景数据,高速路、城区、隧道,分别算一下坐标差分后的熵值,如果都低于2,那压缩方案才值得投入。另外提醒一句,无损压缩在FPGA里会引入不确定的延迟,如果你们有实时性硬约束,得预留一个旁路开关,压力大时直接绕过去。你目前点云处理链路里,最耗带宽的是哪一级?是原始数据存储还是中间体素栅格化?

压缩能救一点,近内存滤波省不了多少,先做坐标差分再查表,比霍夫曼实在。不过说真的,两颗DDR4都喂不满的话,先看看是不是AXI总线效率太低,调一下burst长度可能比折腾压缩简单。你用的DDR控制器IP是Xilinx默认配置吗?

我理解你现在的处境:带宽打满、帧率被卡在15fps,客户那边又催得紧,换DDR5基本等于重新画板子,周期和成本都扛不住。先说结论:压缩和近内存计算都能救一部分,但它们的定位不一样,你得先想清楚瓶颈到底在哪一步。
如果瓶颈是原始点云从DDR读到FPGA的流量太大,那无损差分编码确实值得试。激光雷达点云有个特点:相邻点(尤其同一条扫描线内)的坐标差值和反射率差值都很小,动态范围往往只有原始位宽的1/3到1/2。你按扫描线或按距离门分块,对每块内的坐标做16位差分,再对差值做截断编码,压缩比做到2倍以上很常见。反射率单独处理,不要和坐标混在一起,因为它分布更均匀,单独做查表熵编码更稳。但要注意,霍夫曼变长码在FPGA里解码很吃LUT和时序,车规场景里最坏情况延迟必须可控,所以我个人更推荐定长截断编码,虽然压缩比略低,但流水线简单,不会在某个极端点云帧上突然卡住。
近内存滤波是另一条路,它的核心不是减少读流量,而是减少无效读。比如你体素下采样,传统做法是把整个体素网格从DDR搬进FPGA,累加完再写回,这里面大量读写是空体素或低密度体素。如果你把下采样逻辑挪到DDR控制器和AXI互联之间,用片上SRAM做部分累加器,只在写回时输出非空体素,那么写带宽能省掉不少。但读带宽改善有限,因为滤波本身还是要读原始点。所以如果你的瓶颈在读,这条路帮不上大忙;如果瓶颈在写(比如中间结果反复落DDR),那它比压缩更直接。
我的建议是:先花两天做数据特征统计,把你们实际点云在不同距离、不同天气下的坐标差值和反射率分布画出来,算一下理论压缩比,再对比你的延迟预算。一般来说,如果压缩比能到2以上且延迟增加在10%以内,优先做差分截断编码;如果压缩比不到1.5,那不如把精力放在调AXI burst长度和合并中间处理级上。你现在的DDR控制器IP是用的Xilinx默认配置吗?burst长度和outstanding transaction数调过没有?很多情况下这两项改一下,带宽利用率能提20%。

我觉得你可能把问题想复杂了。先别急着上霍夫曼或者近内存,你确定DDR带宽是被原始点云吃掉的,还是被你自己代码里反复搬运的中间结果吃掉的?我见过太多Zynq上的案例,点云进来先转成世界坐标,再做地面分割,再做聚类,每一级都把上一级的完整输出写回DDR,下一级再读出来。这种场景下,你加压缩反而增加延迟,因为每一级都要先解压再处理。正确做法是把两级处理合并成单次遍历,让中间坐标以量化后的定点格式在流水线里直接传递,不落DDR。我们之前有个项目,最初也是带宽打满,后来发现坐标转换模块把原始点云读了三次,改成流水线直接传中间量,带宽立刻降了30%,根本没碰压缩。
如果确认是原始数据量本身太大,那压缩确实有用。但别对全帧做统一编码,雷达点云稀疏性很强,按扫描线分块后,局部坐标差值的动态范围会小很多,压缩比能到2.5以上。反射率单独做静态霍夫曼表,坐标差分用固定位宽截断编码,这样最稳。近内存滤波我的经验是收益不如压缩直接,除非你把体素下采样做到DDR控制器和AXI互联之间,用片上SRAM做累加器,写回时只写非空体素,这能减少写带宽,但读带宽省不了多少。你先告诉我,你的点云密度分布大概什么情况?是近处密集远处稀疏,还是均匀分布?这直接决定分块策略选哪种。

说点不太一样的东西吧。压缩和近内存计算在车规里有个隐藏风险:确定性。你拿差分编码去压点云,压缩比是随场景变的——高速上稀疏,城区里密集,压缩比可能从2.5掉到1.3。如果你帧率是硬实时要求,那最坏情况下的带宽必须预留,这等于压缩白做。所以工程上更实际的做法是:压一个固定比例,比如把坐标从32位截到16位,反射率从16位压到8位,牺牲一点精度换带宽确定性,这叫近无损,客户那边也好交代。霍夫曼那种变长码,学术界喜欢,产线上真的少用,因为解码器在最坏情况下可能比原始数据还慢。近内存计算我倒觉得值得投,但别叫这个名字,内部叫『分布式预处理』就行。把体素哈希表放在DDR控制器旁边的BRAM里,点云边进边累加,只把满的体素写回,稀疏区域几乎不产生写流量。这个对城区密集场景特别有效,因为大部分体素是空的,你省掉的是海量无效写。不过它需要你重新设计下采样算法,不能直接用现成的PCL代码移植。你现在用的是Zynq UltraScale+哪颗片子?BRAM总量不一样,方案能落地的程度差别很大。

我是做嵌入式软件转FPGA的,说下我踩过的坑。你这个问题我一开始也想走压缩,后来发现先得把DDR带宽的『真实利用率』搞清楚。Xilinx默认的DDR控制器IP,如果不开outstanding和低延迟模式,实际带宽可能只有理论值的60%。你先看AXI总线的burst长度是不是设成16了,再检查一下有没有多余的memory barrier。很多时候调完这些,带宽余量能多出20%,根本不用动算法。如果调完还不够,压缩确实有效,但别自己写霍夫曼,Xilinx有个Vitis Library里的LZ4压缩核,虽然是通用数据压缩,但点云坐标差分后喂给它,压缩比能到1.8左右,关键是它不用你管变长码解码,直接AXI接进去就行。近内存计算那个概念,我理解就是把滤波放到DMA路径上,但Zynq的DDR控制器和PL之间没有可编程的中间层,你得自己用AXI interconnect去搭,工作量不小,不如先试压缩。你现在的帧率15fps,目标是多少?如果只是回到30fps,压缩加AXI调优大概率够用。

一句话版:压缩能救一点,近内存滤波省不了多少,先做坐标差分再查表,比霍夫曼实在。不过说真的,两颗DDR4都喂不满的话,先看看是不是AXI总线效率太低,调一下burst长度可能比折腾压缩简单。你用的DDR控制器IP是Xilinx默认配置吗?
发表回答
登录后可在本页底部提交回答