最近在项目中遇到一个反压的问题,简化下模型如下图所示。A模块给其他逻辑发送数据,其他逻辑会返回一定量的数据给B模块,且B模块不能给其他逻辑反压,如图中红色虚线。
在实际测试的过程中,发现B数据接收数据的缓存溢出了。原因其实很简单,就是因为图中的其他逻辑不接受B模块的反压。原因不是很复杂,这样的方案在前期设计的时候要么没有考虑到反压,要么就是认为A模块发送数据的速度“慢”,不会出现B模块溢出的情况。
其实这样的方案会有如下2个问题:
(1)、如果A模块发数据太快,导致其他逻辑给B模块返回的数据也比较快,有可能导致B模块的缓存溢出,也就是开篇提到的上板测试出现的现象;
(2)、要解决上述问题,可降低A模块发送数据的速度,但是 如果降低A模块发送数据的速度,那么系统的性能就有可能降低;另外,到底降低到什么程度B模块的数据缓存才不会溢出。
那到底应该如何解决这样的问题,方法其实也很简单,就是要计算在途数据量,通过在途数据量来控制A模块发送数据的速度,或者说,将B模块的反压直接反到A模块。我们把从A模块出发,但是还没有到达B模块的数据称为在途数据,当B模块z中的缓存,装下所有的在途数据后,如果还有空间,A模块才可以继续发送数据。
1、计算在途数据:数据离开A模块的时候加1,到达B模块的时候减1,计数器的值就是在途数据量,假定了X;
2、获取B模块缓存的剩余空间,设为S;
3、计算B模块反压水限,B模块要能装下所有在途数据,那么它真实的剩余空间为S-X,当S-X小于预先设定的阈值后就要开始反压给A模块,让A模块停止发送数据。随着B缓存中数据被读走,那么S变大,S-X也会变大,这时B缓存又有足够的空间接收数据,反压取消,A模块可以继续发送数据。
这样就很好的解决了上述问题,在B模块缓存不溢出的前提下,A模块最大性能的发送了数据。
上述模型,我们在读DDR时,即给DDR发送读命令,同时接收读数据的时候,也会遇到。采用上述方法就可以最大速度地发送读DDR命令。
没有回复内容