如何在 Rust 中跨多个结构创建连续内存池?

  • 本文关键字:创建 结构 连续 内存 Rust rust
  • 更新时间 :
  • 英文 :


我正在尝试在 Rust 中创建一组使用连续内存块的结构。例如:

<------------ Memory Pool -------------->
[  Child  |  Child  |  Child  |  Child  ]

这些结构:

  • 每个都可能包含不同大小的池切片

  • 初始化后应该允许访问他们的池切片而无需任何阻塞操作(我打算在音频线程上访问它们)。

我对 Rust 很陌生,但我精通C++所以到目前为止的主要障碍是使用所有权语义 - 我猜有一种微不足道的方法可以实现这一点(不使用不安全),但我不清楚解决方案。我写了一个小(破碎的)例子来说明我正在尝试做的事情:

pub struct Child<'a> {
pub slice: &'a mut [f32],
}
impl Child<'_> {
pub fn new<'a>(s: &mut [f32]) -> Child {
Child {
slice: s,
}
}
}
pub struct Parent<'a> {
memory_pool: Vec<f32>,
children: Vec<Child<'a>>,
}
impl Parent<'_> {
pub fn new<'a>() -> Parent<'a> {
const SIZE: usize = 100;
let p = vec![0f32; SIZE];
let mut p = Parent {
memory_pool: p,
children: Vec::new(),
};
// Two children using different parts of the memory pool:
let (lower_pool, upper_pool) = p.memory_pool.split_at_mut(SIZE / 2);
p.children = vec!{ Child::new(lower_pool), Child::new(upper_pool) };
return p; // ERROR - p.memory_pool is borrowed 2 lines earlier
}
}

我更喜欢一个不涉及不安全的解决方案,但我并不完全反对使用它。任何建议将不胜感激,对我如何(错误?在我的示例中使用 Rust。

是的,目前在 Rust 中不可能(或很难)包含对同级数据的引用,例如,就像您在这里所做的那样,一个Vec并切入该Vec作为同一struct中的字段。根据程序的体系结构,您可以通过将原始Vec存储在代码的某些更高级别(例如,如果您不编写库,它可以存在于main()的堆栈上)和某个较低级别的切片引用来解决此问题,编译器可以清楚地推断出它不会在Vec之前超出范围(在CC_之后main()执行此操作)例如,8 已被实例化可以工作)。

这是竞技场分配器的完美用例。有不少。以下演示使用 bumpalo:

//# bumpalo = "2.6.0"
use bumpalo::Bump;
use std::mem::size_of;
struct Child1(u32, u32);
struct Child2(f32, f32, f32);
fn main() {
let arena = Bump::new();
let c1 = arena.alloc(Child1(1, 2));
let c2 = arena.alloc(Child2(1.0, 2.0, 3.0));
let c3 = arena.alloc(Child1(10, 11));    
// let's verify that they are indeed continuous in memory
let ptr1 = c1 as *mut _ as usize;
let ptr2 = c2 as *mut _ as usize;
let ptr3 = c3 as *mut _ as usize;
assert_eq!(ptr1 + size_of::<Child1>(), ptr2);
assert_eq!(ptr1 + size_of::<Child1>() + size_of::<Child2>(), ptr3);
}

也有警告。主要关注的当然是对齐;两个连续分配之间可能会有一些填充。如果这是一个交易破坏者,则由您来确保不会发生这种情况。

另一个是特定于分配器的。例如,此处使用的 bumpalo 竞技场分配器在自身被解除分配时不会drop对象。

除此之外,我相信像这样的更高级别的抽象将有利于你的项目。否则,它只是伪装成 rust 的指针操作 c/c++。

最新更新