一种缓存管理方法及装置
技术领域
本发明涉及数据缓存技术,尤其涉及一种缓存管理方法及装置。
背景技术
在逻辑设计中常常需要使用动态随机存储器(DRAM)、静态随机存储器(SRAM)或现场可编程门阵列(FPGA)内部的随机存储器(RAM)来对数据进行缓存,如何管理缓存空间是逻辑设计中非常重要的一个环节。通常,缓存资源的管理采用先进先出(FIFO)的方式,即依次将报文存入FIFO队列,然后再从FIFO队列中依次取出。
为了满足时延要求,FIFO一般采用尾丢弃(Tail Drop)机制,即在收到包入队请求后,首先判断FIFO是否有空间能够存储一个最大包,如果有,则将收到的数据包放入缓存;否则,直接丢弃该数据包。也就是说,只要FIFO所剩空间不能容纳一个最大包,那么就直接丢弃后续包。在需要入缓存的包较小的情况下,这种做法容易造成本来可以存入缓存的包被错误丢弃,同时也造成了缓存空间的浪费。另外,对于多个通道的报文同时入缓存的情况,为了避免某个通道的报文出现拥塞而导致其它通道的报文也无法读出的情况发生,即为了避免队头堵塞的情况发生,需要为每个通道分别例化FIFO,也就是说,为各个通道分别分配一定的缓存空间。在这种情况下,会出现某个通道的缓存空间被用完了,而其它通道有空闲的缓存空间却不能被拿来使用,这同样会造成缓存空间的浪费。
发明内容
有鉴于此,本发明的主要目的在于提供一种缓存管理方法及装置,提高缓存资源的利用率。
为达到上述目的,本发明提供的缓存管理方法如下:
将缓存空间划分为缓存块,所述缓存块的长度小于最大包长度;
按照缓存块的长度将数据包分成数据块,将分成的数据块逐个写入空闲的缓存块中。
所述将分成的各个数据块逐个写入空闲的缓存块中的过程包括:
申请一个空闲的块地址,将所述数据包的第一个数据块写入申请到的块地址所对应的缓存块中;
当所述数据包中的数据块个数大于1时,再申请一个空闲的块地址,将所述数据包的下一个数据块写入本次中请到的块地址所对应的缓存块中,并且重复执行该步骤,直到所述数据包的所有数据块都被缓存完毕为止。
该方法还包括:
将所述数据包所占用的所有块地址形成一个地址指针链表,在该数据包被从缓存块中发送出去之后,根据该地址指针链表信息释放该数据包所占用的所有块地址。
所述数据包被从缓存块中发送出去之前还包括:
根据所述地址指针链表信息从缓存决中读出所述数据包的所有数据块。
所述将分成的各个数据块逐个写入空闲的缓存块中之后进一步包括:
检验被缓存的数据包是否正确,如果不正确,则释放该数据包所占用的所有块地址。
本发明提供的缓存管理装置包括:存储模块、切割模块、缓存管理模块以及由长度小于最大包长度的缓存块组成的缓存模块,其中,
存储模块,用于按数据块从入通道读取需要缓存的数据包,每读取一个数据块就向缓存管理模块发出一个写缓存模块的块地址申请,在收到缓存管理模块返回的块地址后,将读取的数据块写入缓存模块中与该块地址对应的缓存块中,并在写入缓存模块的数据块为包尾时,将该包信息发送给切割模块,其中,所述数据包中的数据块按照缓存块的长度进行划分,所述包信息包括包的首地址和数据块个数信息;
缓存管理模块,用于在收到存储模块发送来的块地址申请后,向存储模块返回一个空闲的块地址,并将当前返回的空闲块地址记录为上一个空闲块地址的下一个块地址,建立起地址指针链表,并在收到切割模块发送来的地址释放请求后,根据其中携带的首地址、数据块个数及自身建立的地址指针链表释放该包所占用的所有块地址;
切割模块,用于根据收到的包信息从缓存模块中读出该包的所有数据块并发送出去,并向缓存管理模块发送携带该包的首地址和数据块个数的地址释放请求,请求缓存管理模块释放该包所占用的所有块地址。
当所述存储模块对应一个以上的入通道时,所述存储模块进一步用于在向缓存管理模块发送块地址申请时,将所读取数据块所对应的入通道信息发送给缓存管理模块;
所述缓存管理模块收到携带入通道信息的块地址申请后,向存储模块返回一个空闲的块地址,并将当前返回的空闲块地址记录为所述入通道信息所对应入通道的上一个空闲块地址的下一个块地址。
所述切割模块包括:数据读取模块和请求发送模块,其中,
数据读取模块,用于在收到包信息后,根据其中携带的首地址从缓存模块中读出该包的第一数据块并发送出去;如果其中携带的数据块个数大于1,则将当前读出的数据块的块地址携带在地址查询请求中发送给缓存管理模块,以获得下一个块地址,并在收到缓存管理模块返回的块地址后,根据缓存管理模块返回的块地址从缓存模块中读出下一数据块并发送出去,且重复执行该步骤直到该包的所有数据块都被发送出去为止;并且,在包发送出去之后,将该包的首地址及数据块个数信息发送给请求发送模块;
请求发送模块,用于将数据读取模块发送过来的信息携带在地址释放请求中发送给缓存管理模块,请求缓存管理模块释放该包所占用的所有块地址;
所述缓存管理模块,还用于在收到数据读取模块发送来的地址查询请求后,通过查询自身建立的地址指针链表获取该地址查询请求中携带的块地址所对应的下一个块地址,并将获取的下一个块地址返回给数据读取模块。
该装置进一步包括:位于存储模块和切割模块之间的解析模块,
所述存储模块,用于将包信息发送给解析模块;
所述解析模块,用于在收到包信息后检验该包是否正确,如果包正确,则将所述包信息发送给切割模块;如果包错误,则向缓存管理模块发送携带包的首地址和数据块个数的地址释放请求;
所述缓存管理模块,进一步用于在收到解析模块发送来的地址释放请求后,释放该包占用的所有块地址。
所述缓存管理模块包括:地址申请模块、地址指针建链模块、地址释放模块、地址链表查询模块、链表信息存储模块以及三个队列,其中,
第一队列,用于存储来自切割模块的地址释放请求;
第二队列,用于存储来自解析模块的地址释放请求;
第三队列,用于存储空闲的块地址;
链表信息存储模块,用于存储地址指针链表信息;
地址申请模块,用于在收到来自存储模块的块地址申请后,从第三队列中读出一个空闲的块地址返回给存储模块,并将该返回的块地址发送给地址指针建链模块,当所述存储模块对应一个以上的入通道时,进一步将收到的块地址申请中携带的入通道信息发送给地址指针建链模块;
地址指针建链模块,用于在收到地址申请模块发送来的块地址后,将该块地址记录为上一个空闲块地址的下一个块地址,或者,在存储模块对应一个以上的入通道时,将当前收到的块地址记录为收到的入通道信息所对应入通道的上一个空闲块地址的下一个块地址,建立起地址指针链表,并将建立的地址指针链表保存在链表信息存储模块中;
地址释放模块,用于从第一队列和第二队列读取地址释放请求,将地址释放请求中携带的首地址写入第三队列;如果地址释放请求中携带的数据块个数大于1,则通过查询链表信息存储模块中的地址指针链表获取当前写入第三队列的块地址的下一个块地址,然后将获取的下一个块地址写入第三队列,且重复执行该步骤直到包所占用的所有块地址都被释放完毕为止;
地址链表查询模块,用于在收到切割模块发送来的地址查询请求后,通过查询链表信息存储模块中的地址指针链表获取该地址查询请求中携带的块地址所对应的下一个块地址,并将获取的下一个块地址返回给切割模块。
所述缓存管理模块包括:地址申请模块、地址指针建链模块、地址释放模块、地址链表查询模块、两个链表信息存储模块以及三个队列,其中,
第一队列,用于存储来自切割模块的地址释放请求;
第二队列,用于存储来自解析模块的地址释放请求;
第三队列,用于存储空闲的块地址;
第一链表信息存储模块和第二链表信息存储模块,均用于存储地址指针链表信息;
地址申请模块,用于在收到来自存储模块的块地址申请后,从第三队列中读出一个空闲的块地址返回给存储模块,并将该返回的块地址信息发送给地址指针建链模块,当所述存储模块对应一个以上的入通道时,进一步将收到的块地址申请中携带的入通道信息发送给地址指针建链模块;
地址指针建链模块,用于在收到地址申请模块发送来的块地址后,将该块地址记录为上一个空闲块地址的下一个块地址,或者,在存储模块对应一个以上的入通道时,将当前收到的块地址记录为收到的入通道信息所对应入通道的上一个空闲块地址的下一个块地址,建立起地址指针链表,并将建立的地址指针链表分别保存在第一链表信息存储模块和第二链表信息存储模块中;
地址释放模决,用于从第一队列和第二队列读取地址释放请求,将地址释放请求中携带的首地址写入第三队列;如果地址释放请求中携带的数据块个数大于1,则通过查询第一链表信息存储模块中的地址指针链表获取当前写入第三队列的块地址的下一个块地址,然后将获取的下一个块地址写入第三队列,且重复执行该步骤直到包所占用的所有块地址都被释放完毕为止;
地址链表查询模块,用于在收到切割模块发送来的地址查询请求后,通过查询第二链表信息存储模块中的地址指针链表获取该地址查询请求中携带的块地址所对应的下一个块地址,并将获取的下一个块地址返回给切割模块。
由此可见,本发明所提供的将整个缓存空间划分为多个小的缓存块,并按照缓存块的大小将数据包分成若干个数据块进行缓存的方案,能够有效利用缓存空间,提高缓存资源的利用率,并且能够避免短包被错误丢失。另外,根据缓存块的块地址进行报文存取的方式非常便利,各个用户之间的数据不会相互影响,即使在多通道报文同时入缓存的情况下也不会发生队头堵塞的情况,这样,就无需进行FIFO例化,不会出现某个通道的缓存空间被用完了,而其它通道有空闲的缓存空间却不能被拿来使用的情况,从而提高了缓存资源的利用率。
附图说明
图1为本发明实施例中的一种缓存管理装置结构示意图。
图2为图1所示缓存管理装置的工作过程示意图。
图3为本发明实施例中的另一种缓存管理装置结构示意图。
图4为本发明实施例中的一种缓存管理模块结构示意图。
图5为本发明实施例中的另一种缓存管理模块结构示意图。
具体实施方式
由背景技术描述可见,现有的缓存管理方法容易造成缓存资源的浪费。为了提高缓存资源利用率,本发明提供了一种缓存管理方法,其基本思想是:将缓存空间划分为多个小的缓存块,对于来自入通道的需要进行缓存的数据包,不是按整包进行存取,而是根据缓存块的长度将数据包分成若干数据块,然后再将分成的数据块逐个写入空闲的缓存块中;当缓存的数据包被发送出去后,再释放该包所占用的所有缓存块。
其中,所述缓存块的大小可根据实际需求进行划分,但其长度应小于最大包长度。比如,假设最大包长度为16K字节,整个缓存空间的大小为256M字节,则可以将整个缓存空间划分为4M个大小均为64字节的缓存块。在这种情况下,如果某个需要进行缓存的包的长度为256字节,则可以将该包分成4个长度均为64字节的数据块,每个数据块分别占用一个缓存块;如果该包长度为260字节,则需要将该包分成5个数据块,且每个数据块分别占用一个缓存块,其中,前4个数据块的长度均为64字节,第5个数据块为包尾,其长度为4字节。也就是说,为非包尾的数据块的长度与缓存块的长度一致,为包尾的数据块的长度小于等于缓存块的长度。
将整个缓存空间划分为多个小的缓存块,并按照缓存块的大小将数据包分成若干个数据块进行缓存的方案,能够有效利用缓存空间,提高缓存资源的利用率,并且能够避免短包被错误丢失的情况发生。
为使本发明的目的、技术方案及优点更加清楚明白,下面参照附图并举实施例,对本发明作进一步详细说明。
图1所示为本发明实施例中的缓存管理装置结构示意图,主要包括:存储模块(STORE)、缓存模块(BUFFER)、切割模块(SEG)和缓存管理模块(BM)。其中,STORE模块用于从入通道接收报文,并将收到的报文写入BUFFER模块中;BUFFER模块用于缓存STORE模块写入的报文;SEG模块用于从BUFFER模块中读出报文,并将读出的报文发送出去;BM模块用于管理BUFFER模块中各个缓存块的块地址信息,负责块地址的申请和释放。
下面对图1中各个模块的工作过程进行详细说明。参见图2所示,该过程主要包括以下步骤:
步骤201:STORE模块按数据块从入通道读取报文,并且每读取一个数据块就向BM模块发出一个写BUFFER的块地址申请。
其中,将数据包划分成数据块的操作由STORE模块之前的入通道模块RX完成。RX负责按照缓存块的长度将一个数据包分成若干个数据块,STORE模块在进行数据包缓存时,依次读取构成该包的各个数据块,并且每读取一个数据块就发出一个写BUFFER的块地址申请。
步骤202:BM模块收到STORE模块发出的块地址中请后,向STORE模块返回一个空闲的块地址。
这里,BM模块内部需要维护一张地址指针链表,其中记录各个块地址所对应的下一个块地址。
如果STORE模块只对应一个入通道,则BM模块直接将当前向STORE模块返回的空闲块地址记录为上一个空闲块地址的下一个块地址,建立起地址指针链表。其中,所述上一个空闲块地址是指BM模块上一次发送给STORE模块的空闲块地址。对于BM模块向STORE模块发送的第一个空闲块地址,BM模块可以将该块地址信息记录在指定的区域。
如果STORE模块对应多个入通道,则STORE模块在向BM模块发送块地址申请时,还需要将报文所对应的入通道信息如端口号发送给BM模块。BM收到后,向STORE模块返回一个空闲的块地址,并将当前返回的空闲块地址记录为所述入通道信息所对应入通道的上一个空闲块地址的下一个块地址。其中,所述入通道的上一个空闲块地址是指BM模块上一次分配给该入通道的空闲块地址。
步骤203:STORE模块收到BM模块返回的块地址后,将收到的数据块写入BUFFER中与该块地址相对应的缓存块中。
并且,如果STORE模块接收到的数据块为包尾,则STORE模块还需要将该包信息传送给后级SEG模块。其中,所述包信息包括:构成该包的数据块个数、该包第一个数据块的块地址即首地址,以及一些相关信息。所述相关信息包括:报文类型、源媒质接入控制(MAC)地址、目的MAC地址、端口号等。
步骤204:SEG模块收到STORE模块传送过来的包信息后,根据包信息从BUFFER中读出该包的所有数据块并发送出去。
步骤204的具体操作过程如下:首先,SEG模块根据包信息中携带的首地址从BUFFER中读出该包的第一个数据块并发送出去。如果该包的数据块个数大于1,则SEG模块还需要向BM模块发送携带包首地址的地址查询请求,请求获得该包的第二个数据块在BUFFER模块中的块地址;BM模块收到后,通过查找自身维护的地址指针链表获得所述首地址所对应的下一个块地址,然后将获得的下一个块地址发送给SEG模块;之后,SEG模块再根据收到的下一个块地址从BUFFER模块中读出该包的第二个数据块并发送出去。对于构成该包的后续数据块的处理与第二个数据块的处理类似,都是根据前一个数据块的块地址从BM模块中获取下一个数据块在BUFFER模块中的块地址,然后再从BUFFER模块中读出数据块并发送出去,直到该包的最后一个数据块被发送出去为止。
步骤205:在一个包发送完毕后,SEG模块向BM模块发出地址释放请求消息,请求BM模块释放该包所占用的所有块地址,所述地址释放请求消息中携带了该包的首地址及数据块个数等信息。
步骤206:BM模块收到SEG模块发送来的地址释放请求消息后,根据该消息中携带的首地址、数据块个数及自身维护的地址指针链表逐个释放该包所占用的所有块地址。
为更加清楚起见,下面对图2所示过程进行举例说明。比如,入通道RX0有一个包入队请求,该包需要占用BUFFER中的两个缓存块。STORE模块首先读取RX0入队的第一个数据块,并向BM模块发出写BUFFER的块地址申请,假设BM模块分配给第一个数据块的块地址为11,则STORE模块将第一个数据块写入BUFFER中与块地址11对应的缓存块中。接下来,STORE模块继续读取该包的第二个数据块,同时也向BM模块发出块地址申请,假设BM模块分配给第二个数据块的块地址为55,则STORE模块将第二个数据块写入BUFFER中与块地址55对应的缓存块中,并且,BM模块记录11的下一个块地址为55。另外,由于第二个数据块是该包的包尾,因此,STORE模块还需要将该包的首地址11、数据块个数2以及其它的一些相关信息传送给SEG模块。SEG模块收到后,根据包信息中的首地址11从BUFFER中读出第一个数据块,由于包信息中携带的数据块个数是2,因此SEG模块还需要将11发送给BM模块,请求获得下一个数据块的块地址;BM模块通过查找自身维护的地址指针链表可知11的下一个块地址是55,故将55返回给SEG模块;SEG模块收到后,根据块地址55从BUFFER中读出第二个数据块并发送出去。根据包信息中携带的数据块个数可知,第二个数据块是该包的最后一个数据块,故SEG模块在将第二个数据块发送出去之后,将该包的首地址及数据块个数等信息携带在地址释放请求消息中发送给BM模块,请求进行地址释放;BM模块收到后,根据首地址及数据块个数信息逐个进行地址释放,即释放块地址11和55。
可见,将整个缓存空间划分为多个小的缓存块,并按照缓存块的大小将数据包分成若干个数据块进行缓存的方案,能够有效利用缓存空间,提高缓存资源的利用率,并且能够避免短包被错误丢失。另外,根据缓存块的块地址进行报文存取的方式非常便利,各个用户之间的数据不会相互影响,即使在多通道报文同时入缓存的情况下也不会发生队头堵塞,这样,就无需进行FIFO例化,不会出现某个通道的缓存空间被用完了,而其它通道有空闲的缓存空间却不能被拿来使用的情况,从而提高了缓存资源的利用率。
为了防止错误的包占用缓存资源,进一步提高缓存资源的利用率,还可以在图1中增加一个解析模块(PARSE),用于检验包的正确性。图3示出了增加PARSE模块后的缓存管理装置结构示意图。其中,PARSE模块位于STORE模块和SEG模块之间,用于接收STORE模块发出的包信息,并根据包信息中所携带的内容检验该包的正确性,比如根据源MAC地址和目的MAC地址进行检验,如果该包正确,则将该包信息传送给SEG模块;如果该包错误,则向BM模块发送地址释放请求消息,将该包的首地址和数据块个数等信息发送给BM模块。BM收到后,逐个释放该包所占用的所有块地址。在图3中,STORE模块将收到的数据块存入BUFFER以及SEG模块根据包信息从BUFFER中读出数据块的具体操作过程与图1一致,这里不再一一赘述。
由以上描述可见,BM模块主要用于负责块地址的申请和释放。下面对BM模块的结构及具体工作过程进行详细说明。参见图4所示的BM模块结构示意图,包括:地址申请模块、地址指针建链模块、地址释放模块、地址链表查询模块以及1个RAM和3个FIFO。其中,FIFO0用于存储SEG模块发送来的地址释放信息;FIFO1用于存储PARSE模块发送来的地址释放信息;FIFO3用于存储空闲的块地址;RAM为链表信息存储模块,用于存储地址指针链表信息。其中,FIFO3的宽度为块地址宽度,深度为BUFFER模块被分成的缓存块的个数;RAM的宽度、深度分别与FIFO3的宽度、深度一致。
在图4中,地址申请模块用于接收来自STORE模块的块地址申请,并在收到块地址申请后,从FIFO3中取出一个空闲的块地址返回给STORE模块,同时将该块地址信息发送给地址指针建链模块。如果存储模块对应一个以上的入通道,则地址申请模块还会进一步将收到的块地址中请中所携带的入通道信息发送给地址指针建链模决。
如果存储模块只对应一个入通道,则地址指针建链模块在收到地址申请模块发送来的块地址后,可直接将该收到的块地址记录为上一个空闲块地址的下一个块地址,建立起地址指针链表,并将建立的地址指针链表保存在链表信息存储模块RAM中。
如果存储模块对应一个以上的入通道,则地址指针建链模块在收到地址申请模块发送来的块地址及入通道信息后,将当前收到的决地址记录为收到的入通道信息所对应入通道的上一个空闲块地址的下一个块地址,建立起地址指针链表,并将建立的地址指针链表保存在链表信息存储模块RAM中。
地址链表查询模块用于接收来自SEG模块的地址查询请求,通过查找RAM中的地址指针链表获取地址查询请求中携带的块地址所对应的下一个块地址,并将查询得到的块地址返回给SEG模块。
地址释放模块用于从FIFO0和FIFO1中读取地址释放信息,按照地址释放信息中的首地址和数据块个数,逐个释放包所占用的块地址,将这些块地址写入到空闲块地址存储队列FIFO3中。其间的具体操作过程如下:地址释放模块直接将地址释放信息中的首地址写入FIFO3中,释放该首地址;如果数据块个数大于1,则地址释放模块在释放了一个块地址后,还需要将该已释放的块地址发送给地址链表查询模块,以查询该块地址的下一个块地址信息;地址链表查询模块收到后,通过查找RAM中的地址指针链表获取收到的块地址所对应的下一个块地址,然后将获取的下一个块地址返回给地址释放模块;地址释放模块收到后,将收到的块地址写入空闲块地址存储队列FIFO3中,释放该块地址。并且重复执行上述过程,直到包的最后一个块地址被释放完毕为止。
为便于理解,下面通过一个具体的例子对BM模块中块地址的释放过程进行详细说明。比如,假设某个包占用BUFFER中的两个缓存块,第一个块地址为11,第二个块地址为55,RAM中地址11被写入的内容为55。当SEG模块将该包发送出去之后,SEG模块会将该包的首地址11及块个数2写入FIFO0中。地址释放模块从FIFO0中读出该地址释放信息后,首先将首地址11写入到空闲块地址存储队列FIFO3中,然后再向地址链表查询模块发送携带11的地址查询请求;地址链表查询模块收到地址查询请求后,通过查询RAM中存储的地址指针链表,可知11所对应的下一个块地址是55,故将55返回给地址释放模块;地址释放模块收到后,将55写入FIFO3中。至此,该包所占用的所有块地址均被释放完毕。
在图4所示的BM模块结构中,地址释放模块和地址链表查询模块都需要对RAM进行操作。由于RAM的处理能力有限,因此,地址释放模块和地址链表查询模块都对同一个RAM进行操作,容易导致地址释放效率和地址链表查询效率的降低,并最终导致缓存管理出现异常。比如,当地址释放效率较低、FIFO0和FIFO1中的信息无法及时得到处理时,就容易产生释放队列满的情况,FIFO0和FIFO1队列满了以后,SEG模块和PARSE模块就无法再将需要释放的地址信息写入,从而造成异常丢包。
为了克服图4中的问题,图5示出了一种改进后的BM模块结构示意图。在图5中,包括RAM0和RAM1两个链表信息存储模块,它们都存储有地址指针链表信息。与图4所不同的是,图5中的地址指针建链模块要同时向RAM0和RAM1建链。另外,图5中的地址释放模块通过RAM0查询地址指针链表信息,地址链表查询模块通过RAM1查询地址指针链表信息。可见,图5中的地址释放操作和地址链表查询操作被完全独立开来,互不影响,从而提高了地址释放效率和地址链表查询效率。
最后需要说明的是,如果采用图1所示的缓存管理装置结构,则图4和图5所示BM模块中的地址释放模块仅用处理来自SEG模块的地址释放信息。
以上所述对本发明的目的、技术方案和有益效果进行了进一步的详细说明,所应理解的是,以上所述并不用以限制本发明,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。