PMDK
PMDK is popular nowadays. To practice, please start from http://pmem.io.
在 src/examples/libpmem/ 目录下有三个简单的例子:full_copy.c、manpage.c、simple_copy.c。我们选择 full_copy.c 做测试,并在其基础上修改为 copy_mem.c。
在得到的测试数据中可以发现几个明显的拐点,例如:
(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>)
- devdax 模式下,每次 flush 32 字节比 64 字节要慢很多。因为 cache line 的大小是 64 字节。
-
devdax 模式下,每次 flush 128 字节也比 256 字节要慢很多。 推测是 PMEM_MOVNT_THRESHOLD 默认设置为 256 导致的,256 字节以上的数据将采用 Cache of Non-temporal Data 的写 Cache 模式。
$ cat src/libpmem/x86_64/init.c
define MOVNT_THRESHOLD 256
size_t Movnt_threshold = MOVNT_THRESHOLD;
- xfs 模式下,每次 flush 2048 字节也比 4096 字节要慢很多。因为 xfs 的块大小(等同内核的页面大小)是 4096 字节。
- fsdax 模式下,每次 flush 128 字节也比 256 字节要慢很多。因为 fsdax 模式下,首次缺页都会要先写零并持久化。
- fsdax 模式比 devdax 模式大约会慢 2-3 倍。除了缺页写零之外还有哪些额外操作?
Perf 的输出中可以明显看到 fsdax 模式下有很多 memcpy_flushcache 的调用。主要是走/不走 cache 的差别。
fsdax 43.25% copy_mem libpmem.so.1.0.0 [.] memmove_movnt_sse2_clwb 39.21% copy_mem [kernel.vmlinux] [k] memcpy_flushcache devdax 86.16% copy_mem libpmem.so.1.0.0 [.] memmove_movnt_sse2_clwb 7.14% copy_mem libpmem.so.1.0.0 [.] memmove_nodrain_sse2_clwb
那么为什么 fsdax 会有很多 memcpy_flushcache 的调用,而 devdax 没有?从 perf 获得的调用栈:
__libc_start_main main memmove_movnt_sse2_clwb page_fault do_page_fault __do_page_fault handle_mm_fault __handle_mm_fault __xfs_filemap_fault dax_iomap_fault xfs_file_iomap_begin xfs_iomap_write_direct xfs_bmapi_write xfs_bmapi_convert_unwritten blkdev_issue_zeroout submit_bio_wait submit_bio generic_make_request pmem_make_request pmem_do_bvec write_pmem memcpy_flushcache
那么 clwb 函数是怎么定义的?查 libpmem 代码即可。
[[email protected] libpmem]# grep -rwIn memmove_movnt_sse2_clwb /home/test/pmdk-sandbox/src /home/test/pmdk-sandbox/src/libpmem/x86_64/memcpy/memcpy_nt_sse2_clwb.c:34:#define EXPORTED_SYMBOL memmove_movnt_sse2_clwb /home/test/pmdk-sandbox/src/libpmem/x86_64/memcpy_memset.h:83:void memmove_movnt_sse2_clwb(char *dest, const char *src, size_t len);
注意上面那个 #define。找到对应的代码:src/libpmem/x86_64/memcpy/memcpy_nt_sse2.h
void EXPORTED_SYMBOL(char *dest, const char *src, size_t len) { if ((uintptr_t)dest - (uintptr_t)src >= len) memmove_movnt_sse_fw(dest, src, len); else memmove_movnt_sse_bw(dest, src, len); maybe_barrier(); }
Since PMDK is in active development, the best practice is to read the code and follow the changes.
As for CLFLUSH、CLFLUSHOPT、CLWB’s difference, read the code and refer to http://research.cs.wisc.edu/sonar/tutorial/03-hardware.pdf.
links to: https://zedware.github.io
你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:
相关文章
- 云原生底座之上,企业如何借力领跑数字化转型?
- 网易云音乐用户画像资产治理及业务赋能
- 2023年值得关注的五大云安全威胁
- 企业内容管理陷入困境?SaaS工具助力高效解决!
- Java8之22个lambda表达式用法入门示例超简单,这还不会你就Out了
- 「敏捷」也许敏捷就是问题所在
- 如果你公司里的MQ集群崩溃了,你能确保数据绝对不丢失吗?
- 关于chatGPT接入微信公众号
- 如果用chatGPT做个游戏
- 2023 年使用的优秀编程语言
- Vite 配置篇:日常开发掌握这些配置就够了!
- 京东购物车如何提升30%性能
- 项目介绍&机器学习及其应用 | 犀牛鸟精英人才计划首场课题宣讲会
- 设计探索|重新认识UX文案
- 记一次JVM Full GC 引发的线上故障,真是坑!
- 企业营销的内容之痛,腾讯云SaaS工具的破局之道!
- “数实融合”新时代,解读数据治理的新风向!
- EMQX Enterprise 4.4.12&4.4.13 发布:集群负载重平衡、TDengine 3.0 适配以及子表批量插入
- 测试角色在项目各阶段的项目管理tips
- 调度线程池ScheduledThreadPoolExecutor源码解析