13个版本 ()
1.0.0-pre.3 | 2024年5月13日 |
---|---|
1.0.0-pre.2 | 2024年3月13日 |
0.3.0 | 2024年2月28日 |
0.2.3 | 2024年2月26日 |
0.1.5 | 2024年2月24日 |
#131 in 内存管理
185KB
3.5K SLoC
Ferroc:一个多线程无锁内存分配器
Ferroc(由“ferrum”和“malloc”组合而成)是一个用Rust编写的无锁并发内存分配器,主要灵感来自mimalloc
。
这个内存分配器旨在与其他主流内存分配器一样快速,同时提供灵活的配置,例如嵌入式/裸机环境集成。
示例
如果您只想使用另一个内存分配器,您可以使用Ferroc作为具有默认功能的全局分配器
use ferroc::Ferroc;
#[global_allocator]
static FERROC: Ferroc = Ferroc;
fn main() {
// Using the global allocator API.
let _vec = vec![10; 100];
// Manually allocate memory.
let layout = std::alloc::Layout::new::<u8>();
let ptr = Ferroc.allocate(layout).unwrap();
unsafe { Ferroc.deallocate(ptr, layout) };
// Immediately run some delayed clean-up operations.
Ferroc.collect(/* force */false);
}
如果您想要更多控制分配器,您可以禁用默认功能并启用您需要的功能
ferroc = {version = "*", default-features = false, features = ["base-mmap"]}
#![feature(allocator_api)]
use core::pin::pin;
use ferroc::{
arena::Arenas,
heap::{Heap, Context},
base::Mmap,
};
fn main() {
let arenas = Arenas::new(Mmap); // `Arenas` are `Send` & `Sync`...
let cx = pin!(Context::new(&arenas));
let heap = Heap::new(cx.as_ref()); // ...while `Context`s and `Heap`s are not.
// Using the allocator API.
let mut vec = Vec::new_in(&heap);
vec.extend([1, 2, 3, 4]);
assert_eq!(vec.iter().sum::<i32>(), 10);
// Manually allocate memory.
let layout = std::alloc::Layout::new::<u8>();
let ptr = heap.allocate(layout).unwrap();
unsafe { heap.deallocate(ptr.cast(), layout) }.unwrap();
// Immediately run some delayed clean-up operations.
heap.collect(/* force */false);
}
Cargo功能
- 基本功能:泛型
Arenas
、Context
和Heap
; "base-static"
:基本分配器Static
;"base-mmap"
:基于操作系统特定虚拟内存管理器的Mmap
基本分配器(需要std
和libc
);"global"
:全局分配器实例化宏config!
和config_mod!
(默认情况下内部线程局部静态会泄露);"libc"
:libc
依赖(如果您想要pthread
线程局部析构函数,则在config*!
选项中需要pthread
);"default"
:由Mmap
和pthread
线程局部析构函数提供的默认全局分配器Ferroc
(包括所有上述功能);"c"
:为C/C++目标提供C函数以及根目录下生成的C/C++头文件"ferroc.h"
;"c-override"
:覆盖默认的分配器函数,如malloc/free
和operator new/delete
,这对于在C/C++项目中嵌入Ferroc很有用(更多详情请参阅 本节);"track-valgrind"
:基于crabgrind
的Valgrind内存跟踪支持;"finer-grained"
:向小桶中添加更多对象大小类型,减少碎片化,但也将最小对齐从16降低到8,可能会导致某些需要SIMD的程序因对齐错误而失败。
C/C++用户的构建过程
- 下载并安装最新的夜间Rust工具链
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs |\
sh -- -y --toolchain nightly --profile minimal -c rust-src
- 只需使用
cmake
和make
即可
mkdir target && cd target # Required to be `target`. Don't change it to `build` or other names.
cmake .. && make
- 如果您想安装库
sudo make install
CMake自然支持如 --install-prefix
和 --config
这样的常见选项。
还有一些自定义选项(通过 cmake -D
),您可以使用它们
FE_TRACK_VALGRIND
:请参阅上面的"track-valgrind"
;FE_FINER_GRAINED
:请参阅上面的"finer-grained"
;FE_PGO_GATHER
:启用PGO(Profile-Guided Optimization)收集。FE_PGO_USE
:使用从预收集的PGO数据中获得的优化进行构建(这需要在步骤1的第二行追加llvm-tools
)。
基准测试
使用 mimalloc-bench
的子集进行基准测试。在我的笔记本电脑上运行,该电脑拥有16GB的RAM和一个Intel i7-10750H CPU @ 2.60GHz。该过程重复10次。
耗时
内存消耗
注意事项
此crate仅支持当前最新的夜间Rust编译器,并利用了许多不稳定的功能。请谨慎使用。
许可证
根据您的选择,许可如下
- Apache License,版本2.0 (LICENSE-APACHE)
- MIT许可证 (LICENSE-MIT)
。
依赖项
~0–1MB
~10K SLoC