update chunk-nm

This commit is contained in:
codeboss 2025-09-27 23:41:15 +08:00
parent f0fdd7708e
commit 701db4d98d
4 changed files with 42 additions and 114 deletions

View File

@ -2,58 +2,4 @@
ECSMemoryPool::ECSMemoryPool()
{
}
ChunkAccessIndex::ChunkAccessIndex(ElementControlBlock* ecb, uint64_t chunk_type_code)
:_element_bind(MemoryChunk(ecb)), _chunk_type_code(chunk_type_code)
{
}
ChunkAccessIndex::ChunkAccessIndex(const ChunkAccessIndex& other) :_element_bind(other._element_bind),
_chunk_type_code(other._chunk_type_code),
_member_offset(other._member_offset)
{
}
uint64_t ChunkAccessIndex::chunkType() const
{
return _chunk_type_code;
}
uint16_t ChunkAccessIndex::chunkSize() const
{
return _element_bind.typeSize();
}
bool ChunkAccessIndex::contains(uint64_t type_code)
{
return _member_offset.find(type_code) != _member_offset.cend();
}
int8_t ChunkAccessIndex::setMember(uint64_t type_code, uint16_t offset, uint16_t size)
{
if (_element_bind.typeSize() <= offset + size) {
return -1;
}
_member_offset[type_code] = std::make_pair(offset, size);
return 0;
}
unsigned char* ChunkAccessIndex::getLockedDataPtr(uint64_t type_code)
{
auto index_offset = _member_offset.find(type_code);
if (index_offset == _member_offset.cend())
return nullptr;
auto raw_ptr = _element_bind.dataLock();
auto data_target_ptr = raw_ptr + index_offset->first;
return data_target_ptr;
}
void ChunkAccessIndex::releaseData()
{
_element_bind.release();
}
}

View File

@ -21,7 +21,7 @@ concept CompenentType = requires(T t, T other, const QJsonObject & in, QJsonObje
/// <typeparam name="T"></typeparam>
template<typename T> class ChunkRefer : protected MemoryChunk {
public:
ChunkRefer(ElementControlBlock* data) : MemoryChunk(data) { referAdd(); }
ChunkRefer(ChunkControlBlock* data) : MemoryChunk(data) { referAdd(); }
ChunkRefer(const ChunkRefer<T> &other) :MemoryChunk(other.data_ptr) { referAdd(); }
virtual ~ChunkRefer() { referSub(); }
@ -35,24 +35,6 @@ public:
};
class ECSMEMORYPOOL_EXPORT ChunkAccessIndex {
private:
MemoryChunk _element_bind;
uint64_t _chunk_type_code;
std::map<uint64_t, std::pair<uint16_t, uint16_t>> _member_offset;
public:
ChunkAccessIndex(ElementControlBlock* ecb, uint64_t chunk_type_code);
ChunkAccessIndex(const ChunkAccessIndex& other);
uint64_t chunkType() const;
uint16_t chunkSize() const;
bool contains(uint64_t type_code);
int8_t setMember(uint64_t type_code, uint16_t offset, uint16_t size);
unsigned char* getLockedDataPtr(uint64_t type_code);
void releaseData();
};
class ECSMEMORYPOOL_EXPORT ECSMemoryPool {
@ -97,18 +79,18 @@ public:
std::lock_guard<std::mutex> lockx(_pool_protected_);
auto type_code = T::typeCode();
ElementControlBlock* refer_ptr = nullptr;
ChunkControlBlock* refer_ptr = nullptr;
// 获取指定类型关联的内存页
QList<MemoryPage*> page_list = _storage_pages.values(type_code);
// 迭代内存页集合
for (auto page_ptr : page_list) {
auto max_element_cnt = page_ptr->maxCapacity();
auto max_chunk_cnt = page_ptr->maxCapacity();
auto active_cnt = page_ptr->getActiveCount();
// 初级校核可用数量
if (active_cnt < max_element_cnt) {
if (active_cnt < max_chunk_cnt) {
// 逐个查找数据元素
for (auto eidx = 0; eidx < max_element_cnt; eidx++) {
for (auto eidx = 0; eidx < max_chunk_cnt; eidx++) {
auto slice_ptr = page_ptr->getChunkPtr(eidx);
// 访问排他
slice_ptr->page_refer->lock();

View File

@ -1,23 +1,23 @@
#include "memory_pages.h"
MemoryPage::MemoryPage(uint16_t element_size, uint64_t typecode)
MemoryPage::MemoryPage(uint16_t chunk_size, uint64_t typecode)
{
pcb.byte_count_per_element = element_size;
pcb.byte_count_per_chunk = chunk_size;
pcb.total_buffer_size = sizeof(data_buffer);
pcb.typecode_of_element = typecode;
pcb.typecode_of_chunk = typecode;
}
uint16_t MemoryPage::chunkSize() const
{
return pcb.byte_count_per_element - MemoryChunk::data_buffer_offset;
return pcb.byte_count_per_chunk - MemoryChunk::data_buffer_offset;
}
uint16_t MemoryPage::getActiveCount(uint16_t inc) const
{
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
data_ptr->pcb.active_elements_count += inc;
return data_ptr->pcb.active_elements_count;
data_ptr->pcb.active_chunks_count += inc;
return data_ptr->pcb.active_chunks_count;
}
void MemoryPage::accessRecord(uint64_t timepoint_usec) {
@ -39,25 +39,25 @@ std::pair<uint64_t, uint32_t> MemoryPage::getRecords() const {
return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle);
}
ElementControlBlock* MemoryPage::getChunkPtr(int index) {
ChunkControlBlock* MemoryPage::getChunkPtr(int index) {
auto member_cnt = maxCapacity();
auto element_size = chunkRawSize();
auto chunk_size = chunkRawSize();
ElementControlBlock* element_ptr = nullptr;
ChunkControlBlock* chunk_ptr = nullptr;
if (index >= 0 && index < member_cnt) {
element_ptr = (ElementControlBlock*)(data_buffer + index * element_size);
chunk_ptr = (ChunkControlBlock*)(data_buffer + index * chunk_size);
}
else if (index < 0 && index >= -member_cnt) {
element_ptr = (ElementControlBlock*)(data_buffer + (member_cnt + index) * element_size);
chunk_ptr = (ChunkControlBlock*)(data_buffer + (member_cnt + index) * chunk_size);
}
lock();
if (element_ptr) {
element_ptr->page_refer = this;
element_ptr->element_index = index;
if (chunk_ptr) {
chunk_ptr->page_refer = this;
chunk_ptr->chunk_index = index;
}
release();
return element_ptr;
return chunk_ptr;
}
void MemoryPage::lock()
@ -72,17 +72,17 @@ void MemoryPage::release() {
#pragma warning(pop)
}
uint64_t MemoryPage::elementTypeCode() const
uint64_t MemoryPage::chunkTypeCode() const
{
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return pcb.typecode_of_element;
return pcb.typecode_of_chunk;
}
uint16_t MemoryPage::chunkRawSize() const {
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return pcb.byte_count_per_element;
return pcb.byte_count_per_chunk;
}
uint16_t MemoryPage::maxCapacity() const {
@ -90,13 +90,13 @@ uint16_t MemoryPage::maxCapacity() const {
return cnt / this->chunkRawSize();
}
// element =================================================================
// chunk =================================================================
const uint32_t MemoryChunk::data_buffer_offset = MemoryChunk::validOffset();
uint32_t MemoryChunk::validOffset()
{
uint32_t remains = sizeof(ElementControlBlock) % 16;
uint32_t times = sizeof(ElementControlBlock) / 16;
uint32_t remains = sizeof(ChunkControlBlock) % 16;
uint32_t times = sizeof(ChunkControlBlock) / 16;
return (remains ? times + 1 : times) * 16;
}
@ -108,8 +108,8 @@ uint32_t MemoryChunk::rawSize(uint32_t data_type_size)
return (remains ? times + 1 : times) * 16;
}
MemoryChunk::MemoryChunk(ElementControlBlock* access_bind)
: data_ptr((ElementControlBlock*)access_bind) {}
MemoryChunk::MemoryChunk(ChunkControlBlock* access_bind)
: data_ptr((ChunkControlBlock*)access_bind) {}
uint16_t MemoryChunk::typeSize() const
{
@ -122,7 +122,7 @@ void MemoryChunk::accessUpdate(uint64_t time_usec)
data_ptr->page_refer->accessRecord(time_usec);
}
bool MemoryChunk::isActived(ElementControlBlock* refer)
bool MemoryChunk::isActived(ChunkControlBlock* refer)
{
refer->page_refer->lock();
auto mark = refer->refer_count;

View File

@ -8,11 +8,11 @@ class MemoryPage;
/// 内存页访问控制块
/// </summary>
struct PageControlBlock {
uint16_t active_elements_count = 0; // 活跃element数量,决定是否需要卸载
uint16_t byte_count_per_element = 32; // 单个element大小16的倍数带ElementControlBlock
uint16_t active_chunks_count = 0; // 活跃chunk数量,决定是否需要卸载
uint16_t byte_count_per_chunk = 32; // 单个chunk大小16的倍数带chunkControlBlock
uint32_t total_buffer_size = 0; // 可用数据缓冲区大小
uint64_t typecode_of_element = 0; // 元素类型标识码
uint64_t typecode_of_chunk = 0; // 元素类型标识码
uint64_t curr_access_usec = 0; // 最近访问时间点lsbus
@ -25,9 +25,9 @@ struct PageControlBlock {
/// <summary>
/// 元素访问控制块
/// </summary>
struct ElementControlBlock {
struct ChunkControlBlock {
uint32_t refer_count = 0; // 外部元素的引用数量,活跃标志
uint16_t element_index = 0; // 本元素在Page中的索引
uint16_t chunk_index = 0; // 本元素在Page中的索引
uint16_t backup_1 = 0;
MemoryPage* page_refer = nullptr; // 页面关联指针
@ -48,7 +48,7 @@ public:
/// <summary>
/// 构建内存页
/// </summary>
/// <param name="raw_esize_16B">原始element尺寸</param>
/// <param name="raw_esize_16B">原始chunk尺寸</param>
explicit MemoryPage(uint16_t raw_esize_16B, uint64_t typecode);
/// <summary>
@ -90,17 +90,17 @@ public:
void release();
/// <summary>
/// 获取element元素数据访问指针
/// 获取chunk元素数据访问指针
/// </summary>
/// <param name="index">元素索引</param>
/// <param name="active_set">是否设置</param>
/// <returns>数据指针</returns>
ElementControlBlock* getChunkPtr(int index);
ChunkControlBlock* getChunkPtr(int index);
/// <summary>
/// 元素类型码
/// </summary>
/// <returns></returns>
uint64_t elementTypeCode() const;
uint64_t chunkTypeCode() const;
/// <summary>
/// 获取单个元素尺寸
/// </summary>
@ -118,7 +118,7 @@ public:
/// </summary>
class ECSMEMORYPOOL_EXPORT MemoryChunk {
protected:
ElementControlBlock* const data_ptr;
ChunkControlBlock* const data_ptr;
public:
static const uint32_t data_buffer_offset;
@ -128,13 +128,13 @@ public:
/// 数据活跃状态
/// </summary>
/// <returns></returns>
static bool isActived(ElementControlBlock* refer);
static bool isActived(ChunkControlBlock* refer);
/// <summary>
/// 构建内存元素访问接口
/// </summary>
/// <param name="access_bind"></param>
MemoryChunk(ElementControlBlock* access_bind);
MemoryChunk(ChunkControlBlock* access_bind);
/// <summary>
/// 提取关联元素尺寸