参加了个阿里的kv数据库比赛,接触到持久化内存的概率,到现在对这里理解的也不是太深入,只管总结一下。看了官方的书,还有一些代码和官方视频,但是为了参加比赛,还是觉得研究一下代码。初步看了看发现能在比赛上优化的地方还挺多的,所以决定慢慢总结和移植一下。
持久化内存(Persistent Memory)我看网上好像概念已经老早就有了,我是第一次知道,也记不住讲不清。总的来说就是可以掉电不丢数据的内存,是嫌ssd慢了,又出来一个算是ssd和内存的中间层。还有两种模式,可以当普通内存用,相当于扩展普通内存的容量。或者当持久内存用,可以保证掉电不丢数据和快速的读写速度。
libpmem是intel开发的持久化内存开发组件(Persistent Memory Development Kit)里的一个库,属于底层库,libpmemobj等库都是在这基础上开发的。比赛用到,基本不考虑libpmemobj这库,集成太厉害了,libpmem我大体看了代码发现也可以修改移植,能优化不少。而且因为我c语言经验不多,看了源码后发现能学很多东西。所以决定阅读总结加移植代码。
大体的使用思路就是,基于系统调用mmap进行pmem的进程空间地址的映射,这里是内核原生支持了。所以这玩意应该出了很久了,才刚听说,感觉阿里应该属于用的比较早的。之后就跟正常使用内存一样了,而这些操作都是在用户空间,所以效率理论上还有优势,虽然本身速度赶不上内存。持久化操作需要将cpu cache里的数据踢出到内存(evict),刷新到持久内存上。
基本情况就这样,下边看几个基础文件。学到很多代码
core/util.h util.c
这俩都是常用函数集合
#define force_inline __attribute__((always_inline)) inline
#define NORETURN __attribute__((noreturn))
#define barrier() asm volatile("" ::: "memory")
第一个从名字就看出来是强制函数inline,第二个是有时候写的分支没有返回时编译器会有报错,这个可以告诉编译器不要报错。第三个是内存栅栏。
typedef uint64_t ua_uint64_t __attribute__((aligned(1)));
能够指定最少字节对齐数,受连接器限制,不会超过连接器大小。感觉没啥用,但是也可能以后用上,学到东西了。
util_setbit, util_clrbit这个是位操作,这个是会的
util_is_pow2, return v && !(v & (v - 1)); 判断是否是2的幂
__builtin_ctz,__builtin_clz,这个是判断一个数,从开头或者从结尾有多少个零的,厉害了。
其他的就没啥了,看看util.c
util_is_zeroed检查内存为0,应该用不到,记录下。util_checksum_compute,这是是计算一块内存的checksum,已移植,不知道会不会比hash快,这个应该比hash准确,但是比赛还是讲究速度,到时候试试。算法好像是Fletcher64。
valgrind好像能模拟cpu环境,调试程序的,好像书里有写,没太看内容,先记录。
Mmap_align好像用来分配对齐的,这里不知道干啥的,先跳过记录。linux下直接分配的Pagesize = (unsigned long) sysconf(_SC_PAGESIZE)
util_concat_str连接字符串,没用记录.util_localtime获取时间,没用记录
其他的基本用不上了,主要看书看到原理的地方,发现checksum相关内容,有用到,就搜了一下源码,看到这些代码。
上一篇: R语言devtools包和单元测试testthat包
下一篇: 持久化内存编程库libpmem源码阅读-2初始化mmap
0 Responses so far.