答索引构造一问(续)

为什么倒排表的分块方案采用固定数目(fixed number)的,而不是固定大小(fixed size)的?

解答:

       CPU流水线的有效性

FN方案中,由于确定数目,例如128,则压缩和解压很容易做循环展开的优化,没有分支指令。当然倒排表的最后可能不会正好是128,需要padding一些dummydocid,但这种存储损耗,如果有100K词条,每个词条增加127padding的,每个padding3个字节(docidfrequency, hitlist)代价计算,则不过10M而已,和解压快速的收益看非常小。

FS方案中,压缩和解压的过程中要反复判断是否跨块,因此增加的if-then-else这样的branch指令,使得CPU指令预测可能出现错误而导致流水线停滞(通常for循环中是需要避免分支指令的,后面PFOR-DELTA的优化再详细讨论)。

 

   从存储的有效性上看

FN方案,存储致密,只是需要在最后一个blockpadding一些dummydocid

FS方案,如果考虑到每个固定块中需要存放docidlistfreqency, hitlist的话,那么极容易出现跨块,而使得每个block的尾部空间都会有损耗,这个代价是极大的,因此FS的这种方案就不易存放hitlist,给设计带来了局限。

压缩效果的可控性

FN方案,文档数固定,压缩可控,文档数太少压缩效果差,文档数太多解压效率低,不容易出现skip的情况。

FS方案,大小很难固定,固定了大小,文档数也很难控制,文档数多少和压缩效果紧密联系。

 

    当然FS的方案也不是一无是处,由于计算偏移容易(均为字节地址),而FN的方案不可避免的使用比特地址。此前的博文中已有讨论,不再赘述。

 

 为什么说PFORDELTA的压缩方法,压缩效果好,解压速度快?

解答:

    

     关于流水线角度的分析,请参见:http://blog.csdn.net/pennyliang/archive/2010/09/25/5905691.aspx

 

    成片解压,计算量低

         PFORDELTA事实上只是对exception进行了特别处理,而其余小于threshold的数直接按照二进制的形式存取,因此读取一个字节就可以获得一片docid。同时计算时只有加法,没有乘除法,虽然其余的编码方式由于除的均为2的倍数,因此可以通过移位来优化,但从计算的复杂度看,PFORDELTA还是非常有优势,因为看上去其实并没有进行什么“压缩计算”一样。

        

         在docid重排(reordering)的情况下,PFORDELTA的提升

         docid重排问题比较复杂,这涉及到很好的支持docid的clustering,又要支持early termination(更好的docid要往前排),同时还必须这种重排方法要比较简便,分配的docid要完全致密,没有人为的gap。

        

         b值较小情况,block size = 128,而b低于5的情况下的优化

         PFORDELTA算法依赖于b值,而b值过小的情况下,无法在entry中存放下一个exception的位置的偏移量,这种情况下需要特别的优化。

 

         下一篇博客进行深入探讨docid重排,小b值设定情况下的优化对pfor-delta压缩的改进。

 

推荐阅读:

答索引构造一问:http://blog.csdn.net/pennyliang/archive/2010/07/30/5776140.aspx

 

你可能感兴趣的:(答索引构造一问(续))