d创建特定大小缓冲区指针或切片
原文
假设有包含存储内存缓冲的内存管理器.
你想分发这些内存块给程序的其他部分.块大小为PAGE_SIZE.类似这样:
enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;
class BufferPool
{
align(PAGE_SIZE) ubyte[PAGE_SIZE * BUF_POOL_NUM_PAGES] data;
this()
{
mmap(&data, data.sizeof,PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
}
}
现在应该有个返回ubyte的页大小(PAGE_SIZE)指针的取页()(get_page())函数.但只知道如何返回ubyte[]:
ubyte[] get_page(frame_idx_t frame_idx)
{
return data[frame_idx * PAGE_SIZE .. (frame_idx + 1) * PAGE_SIZE];
}
是否可返回ubyte[PAGE_SIZE]*或ref ubyte[PAGE_SIZE]?
简单的转换似乎有效:
enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;
alias frame_idx_t = size_t;
ubyte[10_000] data;
ubyte[PAGE_SIZE]* get_page(frame_idx_t frame_idx)
{
auto ptr = data.ptr + frame_idx * PAGE_SIZE;
return cast(ubyte[PAGE_SIZE]*)ptr;
}
void main() {
}
在C++中等价版如下:
#include <cstddef>
#include <span>
#include <sys/mman.h>
static constexpr size_t PAGE_SIZE = 4096;
static constexpr size_t BUF_POOL_NUM_PAGES = 1024;
class BufferPool
{
private:
alignas(PAGE_SIZE) std::byte data[BUF_POOL_NUM_PAGES * PAGE_SIZE];
public:
BufferPool()
{
mmap(data, BUF_POOL_NUM_PAGES * PAGE_SIZE,PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
//返回页上包含`{T*ptr,len}`的`PAGE_SIZE`字节的胖指针
std::span<std::byte, PAGE_SIZE> get_page(size_t page_num)
{
return std::span<std::byte, PAGE_SIZE>(data + page_num * PAGE_SIZE, PAGE_SIZE);
}
};
也许在带有不变的新类中包装切片(.a),会更好?
因为我想:
1,确保基础引用或指向的数据长度为页大小(PAGE_SIZE)
2,从D的特性中获益
检查切片边界省去了开发过程中的许多麻烦.
或如下会更好?
struct Frame
{
ubyte[] data;
invariant
{
assert(data.length == PAGE_SIZE);
}
}
class BufferPool
{
align(PAGE_SIZE) ubyte[PAGE_SIZE * BUF_POOL_NUM_PAGES] data;
Frame[BUF_POOL_NUM_PAGES] frames;
this()
{
// mmap
foreach (i; 0 .. BUF_POOL_NUM_PAGES)
{
frame_idx_t frame_idx = cast(frame_idx_t) i;
frames[frame_idx].data = data[frame_idx * PAGE_SIZE .. (frame_idx + 1) * PAGE_SIZE];
}
}
}
是的,因为静态数组只是内存中并排的元素(.b).只要长度和对齐方式正确,就可按静态数组转换内存块.
但是,在@safe代码中禁止此转换.
:.a.
有可能,但使用前要检查,因为'不变'要求是成员函数:
这里
为什么不用切片呢?
注意,静态数组是值类型,而且彼此为不同类型,可能导致模板膨胀.
除非需要类,大多数D程序员使用构.
Frame[BUF_POOL_NUM_PAGES] frames;
合理.
:.b.
更准确地说,转换内存为正确大小的静态数组*指针*.静态数组是值类型,传递原始数组,会导致每次都冗余的复制该数组.
浙公网安备 33010602011771号