透明代码大页:让数据库也能用上2MB大页!
背景
大页技术是操作系统中优化内存访问延迟的一种技术,其优化原理与CPU TLB硬件有直接关系,而其优化效果不仅受CPU TLB硬件影响,还需要看应用访存特点。只考虑arm和x86两种平台,已知的大页技术包括透明大页、hugetlbfs、16k和64k全局大页。在合适的场景,大页技术可以提升应用性能达10%以上,尤其是针对当前云上应用逐年增长的内存使用趋势,使用大页技术是其中重要的提升“性能-成本”比例的优化手段。透明大页(Transparent Huge Pages,THP)从2011年开始在Linux内核中已经支持起来,其通过一次性分配2M页填充进程页表,避免多次缺页开销,更深层次从硬件角度优化了TLB缺失开销,在最好情况下,对应用的优化效果达到10%左右。除以上优点外,透明大页(主要供堆栈使用)使用过度也会导致严重的内存碎片化、内存膨胀和内存利用率低等问题,这就是当前透明大页没有在数据库中使用的核心原因,只能感叹“卿本巧技,奈何有坑”。
代码大页在透明大页的基础上,将支持扩展到可执行二进制文件,包括进程二进制文件本身、共享库等可执行数据。与透明大页相比,由于代码大页仅将占比较低且有限的可执行文件页部分转换为大页,从根本上避开了内存碎片以及内存不足的问题。与此同时,由于代码类数据和普通堆栈数据访问热度对整体性能影响不同(主要指代码数据或堆栈数据访问缺页一次的性能影响),导致代码类数据使用大页所提升的性能远大于同样分量的透明大页。所以推广和完善代码大页相比透明大页更加简单和容易。
本文主要介绍我们的代码大页方案以及一些实验阶段性能测试。为了方便阅读,在这里简单归纳了一下L...
MAP_DENYWRITE:被Linux内核屏蔽的flag
一 背景
谈到MAP_DENYWRITE,可能有些陌生。这个flag很少被用户态开发者关注,其中没有被关注的理由主要是“this flag is ignored by os”,简而言之,操作系统(Linux内核)将会忽略掉用户传入的MAP_DENYWRITE标志。回到MAP_DENYWRITE是什么?与MAP_ANONYMOUS、MAP_SHARED、MAP_PRIVATE等一样,是系统调用mmap()函数为映射目标设置映射方式的一种flag。顾名思义,MAP_DENYWRITE表示这段映射的虚拟地址区间不允许写操作,例如,我们通过open()以可写的方式获取文件句柄,将会返回“ETXTBSY: text file is busy”错误。
本文主要介绍MAP_DENYWRITE相关的内容,例如使用了MAP_DENYWRITE的可执行二进制文件和忽略MAP_DENYWRITE的动态共享库。为了描述简单,后面直接使用EXEC和DSO(Dynamic Shared Object)分别表示可执行二进制文件和动态共享库。为了更加清晰的展示MAP_DENYWRITE作用,设计了实验1和实验2来显示用户态可见的差异。同时,借助实验1和实验2也为引出两个疑问:(a)为什么i_writecount会导致“ETXTBSY: text file is busy”;(b)为什么vim“写-存”DSO触发程序“Segment fault”;其答案分别可以在第三节和第四节获取。最后,第五节设计了最后一个实验对实验3进行补充。
二 MAP_DENYWRITE是什么
...