惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
J
Java Code Geeks
V
Visual Studio Blog
H
Help Net Security
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
博客园 - 【当耐特】
B
Blog
Stack Overflow Blog
Stack Overflow Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
GbyAI
GbyAI
博客园 - 司徒正美
博客园 - 叶小钗
Y
Y Combinator Blog
MyScale Blog
MyScale Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - 程鑫

Harness Engineering 介绍与最佳实践 Thriving in a Crowded and Changing World: C++ 2006–2020 读后总结 C++20中对于并发方面的进步 ClickHouse性能调优 - 当磁盘IO是瓶颈的时候 手撸一个C++迭代器 ClickHouse的向量处理能力 STL库的ranges ClickHouse中的各种设置 OLAP与数据仓库和数据湖 关于ClickHouse的一些小技巧 `static_cast` caution ClickHouse中“大列”造成的JOIN的内存超限问题 ClickHouse的JOIN算法选择逻辑以及auto选项 ClickHouse的Join算法 一种高效且节约内存的聚合数据结构的实现 “过早优化是万恶之源”这句话的源头 ClickHouse的WITH-ALIAS是如何实现的 如何与chatgpt共存 多线程与同步 C++编译器选择是否自动生成代码的背后逻辑
mmap访问内存方式
程鑫 · 2024-03-17 · via 博客园 - 程鑫

mmap访问内存方式

请看下面的Java代码,这段程序是取自1brc竞赛的第一名的代码。

public static void main(String[] args) throws IOException, InterruptedException {
    ... ...
    try (var fileChannel = FileChannel.open(java.nio.file.Path.of(FILE), java.nio.file.StandardOpenOption.READ)) {
        long fileSize = fileChannel.size();
        final long fileStart = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize, java.lang.foreign.Arena.global()).address();
        final long fileEnd = fileStart + fileSize;
        final AtomicLong cursor = new AtomicLong(fileStart);
        ... ...
    }
    ... ...
}

该代码显示出了基于mmap的IO操作的高效。下面研究一下为什么这种方式高效。

mmap(memory-mapped files)比一般IO操作(如read/write系统调用)在某些情况下更快的原因主要包括以下几点:

  1. 减少数据复制

    • 使用mmap时,文件被映射到进程的地址空间,使得可以直接读写内存来访问文件内容,省去了内核缓冲区与用户空间缓冲区之间的数据拷贝。当进行顺序读取或者大量随机访问时,这种直接访问方式避免了传统I/O中需要将内核缓存的数据复制到用户程序缓冲区的过程。
  2. 内存管理优化

    • 操作系统能够利用其虚拟内存和页替换机制,只在实际访问页面时才触发物理磁盘I/O(按需分页或预读)。这样可以更高效地利用有限的物理内存资源,并结合操作系统层面的缓存策略提升性能。
  3. 系统调用开销减小

    • 通过mmap读写文件时,一旦完成映射,后续对文件的操作就不必每次都涉及系统调用。而传统的read/write操作每次都会导致从用户态到内核态的切换,这一过程会带来一定的CPU开销。
  4. 缓存一致性

    • mmap映射的文件区域可以受益于操作系统的缓存机制,即如果其他进程也访问同一文件,那么这些更改可以通过缓存同步机制快速传播,无需额外的同步代码。
  5. 连续访问效率

    • 当应用程序对大文件进行连续访问时,由于内存访问的局部性原理(局部性原理指的是程序在执行过程中倾向于访问最近刚刚访问过的数据附近的数据),mmap可能触发硬件级别的预读取机制,从而提前加载接下来可能要访问的数据块,提高整体性能。

然而,在实际应用中,mmap并非总是优于传统的I/O操作。对于小文件、非顺序访问模式或者不完全访问整个文件的应用场景,mmap可能因为映射和维护内存映射表的开销而不占优势。此外,当内存资源紧张时,频繁的换页活动可能会增加磁盘交换,反而降低性能。因此,选择哪种方法取决于具体的应用需求和工作负载特征。