为了更好的阅读效果,推荐下载pdf文档:
详细文章请参考:《jemalloc 深入分析》
https://github.com/everschen/tools/blob/master/DOC/Jemalloc.pdf
https://download.csdn.net/download/ip5108/10941278

2.1. 配对堆Pairing Heap
斐波那契堆主要有两个缺点:编程实现难度较大和实际效率没有理论的那么快(由于它的存储结构和四个指针)。Pairing Heap的提出就是弥补斐波那契堆的两个缺点——编程简单操作的时间复杂度和斐波那契堆一样。
Pairing Heap其实就是一个具有堆(最大堆或最小堆)性质的树,它的特性不是由它的结构决定的,而是由于它的操作(插入,合并,减小一个关键字等)决定的。
一个指针指向该节点的第一个孩子lchild,一个指向它的下个兄弟next,一个指向它的上个兄弟prev(对于最左边的兄弟则指向它的父亲),对于第一个孩子,prev属性表示该孩子的父结点;对于其他结点,prev属性表示该结点的左兄弟。

2.1.1. phn_merge_ordered
把大的作为小的树的最左孩子,插入配对树,小的树如果有孩子作为大的树的根节点的兄弟节点。

2.1.2. ph_merge_siblings
对兄弟节点两两进行merge,merge完后插入FIFO队尾(FIFO是单链表的),再进行后续节点的操作,直到只剩下一个元素为止。
由于一开始没有队尾节点,所以先进行一轮的merge操作,找到队尾和头,然后再进行循环的merge操作,直到只剩下一个节点为止。
排序后返回一个最小值的节点。

2.1.3. ph_merge_aux
对一个树作排序,找到一个最小值,作为树的root。

2.1.4. ph_merge_children
对孩子节点做排序操作,找到一个最小值。

2.1.5. a_prefix##first
对这个树作排序,找到一个最小值并返回。调用ph_merge_aux。

2.1.6. a_prefix##insert
如果树不为空,作为第一个兄弟节点。如果树为空作为root节点。
/* \

  • Treat the root as an aux list during insertion, and lazily \
  • merge during a_prefix##remove_first(). For elements that \
  • are inserted, then removed via a_prefix##remove() before the \
  • aux list is ever processed, this makes insert/remove \
  • constant-time, whereas eager merging would make insert \
  • O(log n). \

2.1.7. a_prefix##remove_first
对这个树作排序,找到一个最小值作为根节点,并且调用ph_merge_children,对孩子节点做排序操作,找到一个最小值作为树的新的根节点。返回原树的根节点。

2.1.8. a_prefix##remove
1)如果被删除的根节点,需要对树做merge。Merge后如果还是根节点,则需要对孩子节点做merge找到一个新的根节点。这样删除后树还是保持最小值在根节点。
2)如果被删除节点是最左孩子节点,则存在父节点。要不不存在父节点。
3)如果被删除节点是一个树,则可以对被删除节点所在的树的孩子节点进行merge,merge后从被删除节点所在的树找新的根节点,如果新的根节点存在,可以用这个节点代替被删除节点,如果该节点不存在,则直接删除这个节点。

2.1.9. 配对堆在jemalloc中的使用
主要用来管理arena_t的runs_avail,和arena_bin_t的runs。
Jemalloc 深入分析
Copyright 2013 Spreadtrum Communications Inc. 6
/* Generate pairing heap functions. */
ph_gen(static UNUSED, arena_run_heap_, arena_run_heap_t, arena_chunk_map_misc_t, ph_link, arena_snad_comp)
#define ph_gen(a_attr, a_prefix, a_ph_type, a_type, a_field, a_cmp)
a_attr void a_prefix##new(a_ph_type *ph)
a_attr bool a_prefix##empty(a_ph_type *ph)
a_attr a_type * a_prefix##first(a_ph_type *ph)
a_attr void a_prefix##insert(a_ph_type *ph, a_type *phn)
a_attr a_type * a_prefix##remove_first(a_ph_type *ph)
a_attr void a_prefix##remove(a_ph_type *ph, a_type *phn)
实际的定义函数如下:
static void arena_run_heap_new(arena_run_heap_t *ph)
static bool arena_run_heap_empty(arena_run_heap_t *ph)
static a_type * arena_run_heap_first(arena_run_heap_t *ph)
static void arena_run_heap_insert(arena_run_heap_t *ph, arena_chunk_map_misc_t *phn)
static a_type * arena_run_heap_remove_first(arena_run_heap_t *ph)
static void arena_run_heap_remove(arena_run_heap_t *ph, arena_chunk_map_misc_t phn)
/
Node structure. */
#define phn(a_type)
struct {
a_type *phn_prev;
a_type *phn_next;
a_type phn_lchild;
}
/
Root structure. */
#define ph(a_type)
struct {
a_type *ph_root;
}

typedef ph(arena_chunk_map_misc_t) arena_run_heap_t;
struct {
arena_chunk_map_misc_t ph_root;
};
struct arena_bin_s {
/

  • All operations on runcur, runs, and stats require that lock be
  • locked. Run allocation/deallocation are protected by the arena lock,
  • which may be acquired while holding one or more bin locks, but not
  • vise versa.
    /
    malloc_mutex_t lock;
    /
  • Current run being used to service allocations of this bin’s size
  • class.
    */
    arena_run_t runcur;
    /
  • Heap of non-full runs. This heap is used when looking for an
  • existing run when runcur is no longer usable. We choose the
  • non-full run that is lowest in memory; this policy tends to keep
  • objects packed well, and it can also help reduce the number of
  • almost-empty chunks.
    / arena_run_heap_t runs;
    /
    Bin statistics. /
    malloc_bin_stats_t stats;
    };
    struct arena_s {
    Jemalloc 深入分析
    Copyright 2013 Spreadtrum Communications Inc. 8
    /
    This arena’s index within the arenas array. /
    unsigned ind;
    ……
    /
  • Size-segregated address-ordered heaps of this arena’s available runs,
  • used for first-best-fit run allocation. Runs are quantized, i.e.
  • they reside in the last heap which corresponds to a size class less
  • than or equal to the run size.
    */ arena_run_heap_t runs_avail[NPSIZES];
    };
    phn(arena_chunk_map_misc_t) ph_link;
    struct {
    arena_chunk_map_misc_t *phn_prev;
    arena_chunk_map_misc_t *phn_next;
    arena_chunk_map_misc_t phn_lchild;
    }
    /
  • Each arena_chunk_map_misc_t corresponds to one page within the chunk, just
  • like arena_chunk_map_bits_t. Two separate arrays are stored within each
  • chunk header in order to improve cache locality.
    /
    struct arena_chunk_map_misc_s {
    /
  • Linkage for run heaps. There are two disjoint uses:
    1. arena_t’s runs_avail heaps.
    1. arena_bin_t conceptually uses this linkage for in-use non-full
  • runs, rather than directly embedding linkage.
    / phn(arena_chunk_map_misc_t) ph_link;
    union {
    /
    Linkage for list of dirty runs. /
    arena_runs_dirty_link_t rd;
    /
    Profile counters, used for large object runs. */
    union {
    void *prof_tctx_pun;
    prof_tctx_t prof_tctx;
    };
    /
    Small region run metadata. */
    arena_run_t run;
    };
    };
    比较函数:arena_snad_comp,先比较arena_sn_comp,如果两个arena_chunk_map_misc_t 来自同一个chunk,则arena_sn_comp结果一样,再用arena_ad_comp直接比较两个地址。

详细文章请参考:《jemalloc 深入分析》
https://github.com/everschen/tools/blob/master/DOC/Jemalloc.pdf
https://download.csdn.net/download/ip5108/10941278

Jemalloc 深入分析 之 配对堆Pairing Heap相关推荐

  1. 配对堆Pairing Heap

    前言 最近做一道Dijkstra的题目,因为边数实在太大了(10910910^9),用STL的priority_queue直接超时(事实上还会MLE).有同学写配对堆的.刚好很久没学习新的数据结构了, ...

  2. 配对堆(Pairing Heap)

    配对堆(Pairing Heap)是一个简单实用的min-heap结构(当然也可以做成max-heap).它是一颗多路树(multiway tree),类似于Leftist Heap和Skew Hea ...

  3. 结构之美——优先队列三大结构(三)——Pairing Heap

    转自http://dsqiu.iteye.com/blog/1714961 1.Pairing Heap简介 斐波那契堆主要有两个缺点:编程实现难度较大和实际效率没有理论的那么快(由于它的存储结构和四 ...

  4. 堆(heap)与栈(stack)的区别(一)

    堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收,但它与数据结构中的堆不是一回事,分配方式类似于链表. 栈(stack):由编译器自动分配和释放,存函数的参数值, ...

  5. 【编程】堆(heap)和栈(stack)的区别

    从C/C++的内存分配(与操作系统相关)上来说,堆(heap),栈(stack)属于内存空间的一段区域. 效率: 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持(有专门的寄存器存放栈的地址,压 ...

  6. C++二叉堆binary heap (附完整源码)

    二叉堆binary heap 二叉堆binary heap 算法的完整源码(定义,实现,main函数测试) 二叉堆binary heap 算法的完整源码(定义,实现,main函数测试) #includ ...

  7. 11.JDK8内存模型、本地方法栈、虚拟机栈、栈帧结构(局部变量表、操作数栈、方法出口、虚拟机栈与本地方法栈的关系、寄存器、方法区、堆(Heap)、jvm中的常量池、Metaspace(元空间))

    11.JDK8内存模型 11.1.本地方法栈(Native Method Stacks) 11.2.虚拟机栈(Java Virtual Machine Stacks) 11.3.栈帧结构 11.3.1 ...

  8. 返回局部变量或临时变量的地址_值传递和地址返回两者在堆区(Heap)应用的三种易错点...

    1.指针变量作为参数进行值传递给函数的形参,并在堆区(Heap)进行内存分配和赋值 程序源码: 1 结果: Segmentation fault (core dumped) 分析: 如上图,指针变量p ...

  9. 看动画学算法之:二叉堆Binary Heap

    文章目录 简介 二叉堆的特性 二叉堆的作用 二叉堆的构建 获取二叉堆的最大值 二叉堆的插入 insert操作的时间复杂度 二叉堆的提取Max操作 extractMax的时间复杂度 创建二叉堆 简介 我 ...

最新文章

  1. 基于三维卷积神经网络的RGB-D显著目标检测
  2. 打印Java数组的最简单方法是什么?
  3. boost::mpl模块bind相关的测试程序
  4. SAP CRM HANA report里 默认filter 的工作机制分析
  5. python变量持久化_Python 数据持久化:JSON
  6. Spring Boot 全局异常机制
  7. IOS 8.0 适配应用图片设计
  8. MySQL高阶面试题
  9. linux 文件系统 xfs、ext4、ext3 的区别
  10. P2207 Photo
  11. Atitit 安全审计法 目录 1. 安全审计数据结构 1 2. Expame 提现流程 1 2.1. 获取提现钱的数据余额 1 2.2. 扣去余额 1 2.3. 开始safe log 2 2.4.
  12. Davinci Configurator之User Config File配置功能
  13. TP6如何配置多应用?
  14. Excel/WPS如何查找重复数据
  15. 不错的一个团队积分互换游戏
  16. 桌面上的文件夹存储路径是什么?桌面文件夹误删了怎么找回
  17. (与运算)、|(或运算)、^(异或运算)等运算符的解释与运用
  18. 液晶LCD1602驱动代码
  19. JAVA获取tomcat信息
  20. 微博将于今日晚间挂牌上市 最高融资金额4.37亿美元

热门文章

  1. Windows下安装Boot Camp提示版本不适用
  2. 计算机的硬件故障维修,计算机硬件故障分析与解决方法
  3. 中国开源项目哪家强?看看阿里,百度,腾讯,360,新浪,网易,小米等都开源了什么
  4. ansys 软件安装注意事项
  5. 【2021版PHP高级教程-Swoole4.X从入门到精通全套高级实战】
  6. ST-Link SWD接口接线
  7. FFmpeg —— Linux下进行编译配置(硬件加速编解码)
  8. PS PNG导出的时候是否交错有什么影响
  9. 2022 CCPC 威海 赛后总结
  10. ESP8266-Arduino编程实例-ILI9341-TFT LCD驱动(基于TFT_eSPI库)