差分编码 Differential Encoding

Differential Encoding

百度百科:

差分编码(differential encoding)指的是对数字数据流,除第一个元素外,将其中各元素都表示为各该元素与其前一元素的差的编码。

差分编码,又称增量编码,是以序列式资料之间的差异储存或传送资料的方式(相对于储存传送完整档案的方式)。在需要档案改变历史的情况下的差分编码有时又称为差分压缩。差异储存在称为“delta”或“diff”的不连续档案中。由于改变通常很小(平均占全部大小的2%),差分编码能大幅减少资料的重复。一连串独特的delta档案在空间上要比未编码的相等档案有效率多了。

差分编码的简单例子是储存序列式资料之间的差异(而不是储存资料本身):不存“2, 4, 6, 9, 7”,而是存“2, 2, 2, 3, -2”。单独使用用处不大,但是在序列式数值常出现时可以帮助压缩资料

差分编码是一个数字编码技术,我们熟悉的相关应用是差分曼彻斯特编码:每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示"0"或"1",有跳变为"0",无跳变为"1"。
差分编码 Differential Encoding_第1张图片

前面提到 “差分编码在序列式数值常出现时可以帮助压缩资料”,是否在存储领域或其他领域有所应用?

clfB-tree: Cacheline Friendly Persistent B-tree for NVRAM(ACM Trans 2018) 对 B-tree 节点应用了差分编码的思想,压缩键/指针的大小以存储更多条目。

clfB-tree with Differential Encoding

clfB-tree 是一种 b 树结构,它的树节点适合于单个缓存线。因为缓存线是32字节或64字节,所以不能容纳大量的条目。为了在clfB-tree 节点中存储更多的条目,提出了差分编码:计算第一个键/指针和其他键/指针之间的差值,并且只将差值存储在树节点中。使用差分编码,可以减少每个键和指针使用的字节数,从而在树节点中存储更多的条目。

如果缓存行大小为 64 字节,键和指针为 8 字节,那么树节点的度仅为 4,使得树的高度非常高。
根据 B-tree 的性质,树节点通常存储类似的键和指针(键是相似的;堆管理器通常分配连续的内存块导致内存地址相似)。
因此 clfB-tree 用更少的字节计算和存储键和指针之间的差异,而不是存储整个键和指针,可以有效地压缩键和指针,提高树节点的利用率。
差分编码 Differential Encoding_第2张图片
上图显示了一个 clfB-tree 内部节点的布局。clfB-tree 内部节点的大小设置为缓存行大小(示例中为64字节)。前两个字节存储关于树节点的元数据。第一个字节指示树节点是叶节点还是内部节点,以及树节点中有多少个键。第二个字节存储用于编码指针和键的字节数。

第一个指针/键正常存储。对于其余的指针和键,计算与第一个值的差值,并确定需要多少字节来存储最大差值。

如果指针编码和键编码都需要每个 1 字节,那么 64 字节的树节点可以有最多 23 个键和 24 个子指针。可以进一步以位为单位压缩键、指针和元数据,按位编码需要更多的计算,并且降低了整体索引性能。
最坏的情况下,尽管不太可能,但差分编码存储指针和键仍然需要8个字节。此时 64 字节的树节点最多可以保存 3 个键和 4 个子指针。

如果一个键是字符串类型,大于缓存线,可以像前缀 B-tree(prefix B-tree)一样将键都有的前缀字符串存储在一个单独的内存块,所有键只需存储不同的字符串。


参考:
百度百科
clfB-tree: Cacheline Friendly Persistent B-tree for NVRAM

你可能感兴趣的:(知识点,数据结构)