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

@ -3,57 +3,3 @@
ECSMemoryPool::ECSMemoryPool() 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> /// <typeparam name="T"></typeparam>
template<typename T> class ChunkRefer : protected MemoryChunk { template<typename T> class ChunkRefer : protected MemoryChunk {
public: public:
ChunkRefer(ElementControlBlock* data) : MemoryChunk(data) { referAdd(); } ChunkRefer(ChunkControlBlock* data) : MemoryChunk(data) { referAdd(); }
ChunkRefer(const ChunkRefer<T> &other) :MemoryChunk(other.data_ptr) { referAdd(); } ChunkRefer(const ChunkRefer<T> &other) :MemoryChunk(other.data_ptr) { referAdd(); }
virtual ~ChunkRefer() { referSub(); } 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 { class ECSMEMORYPOOL_EXPORT ECSMemoryPool {
@ -97,18 +79,18 @@ public:
std::lock_guard<std::mutex> lockx(_pool_protected_); std::lock_guard<std::mutex> lockx(_pool_protected_);
auto type_code = T::typeCode(); auto type_code = T::typeCode();
ElementControlBlock* refer_ptr = nullptr; ChunkControlBlock* refer_ptr = nullptr;
// 获取指定类型关联的内存页 // 获取指定类型关联的内存页
QList<MemoryPage*> page_list = _storage_pages.values(type_code); QList<MemoryPage*> page_list = _storage_pages.values(type_code);
// 迭代内存页集合 // 迭代内存页集合
for (auto page_ptr : page_list) { 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(); 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); auto slice_ptr = page_ptr->getChunkPtr(eidx);
// 访问排他 // 访问排他
slice_ptr->page_refer->lock(); slice_ptr->page_refer->lock();

View File

@ -1,23 +1,23 @@
#include "memory_pages.h" #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.total_buffer_size = sizeof(data_buffer);
pcb.typecode_of_element = typecode; pcb.typecode_of_chunk = typecode;
} }
uint16_t MemoryPage::chunkSize() const 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 uint16_t MemoryPage::getActiveCount(uint16_t inc) const
{ {
auto data_ptr = const_cast<MemoryPage*>(this); auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected); std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
data_ptr->pcb.active_elements_count += inc; data_ptr->pcb.active_chunks_count += inc;
return data_ptr->pcb.active_elements_count; return data_ptr->pcb.active_chunks_count;
} }
void MemoryPage::accessRecord(uint64_t timepoint_usec) { 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); 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 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) { 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) { 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(); lock();
if (element_ptr) { if (chunk_ptr) {
element_ptr->page_refer = this; chunk_ptr->page_refer = this;
element_ptr->element_index = index; chunk_ptr->chunk_index = index;
} }
release(); release();
return element_ptr; return chunk_ptr;
} }
void MemoryPage::lock() void MemoryPage::lock()
@ -72,17 +72,17 @@ void MemoryPage::release() {
#pragma warning(pop) #pragma warning(pop)
} }
uint64_t MemoryPage::elementTypeCode() const uint64_t MemoryPage::chunkTypeCode() const
{ {
auto data_ptr = const_cast<MemoryPage*>(this); auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected); 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 { uint16_t MemoryPage::chunkRawSize() const {
auto data_ptr = const_cast<MemoryPage*>(this); auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected); 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 { uint16_t MemoryPage::maxCapacity() const {
@ -90,13 +90,13 @@ uint16_t MemoryPage::maxCapacity() const {
return cnt / this->chunkRawSize(); return cnt / this->chunkRawSize();
} }
// element ================================================================= // chunk =================================================================
const uint32_t MemoryChunk::data_buffer_offset = MemoryChunk::validOffset(); const uint32_t MemoryChunk::data_buffer_offset = MemoryChunk::validOffset();
uint32_t MemoryChunk::validOffset() uint32_t MemoryChunk::validOffset()
{ {
uint32_t remains = sizeof(ElementControlBlock) % 16; uint32_t remains = sizeof(ChunkControlBlock) % 16;
uint32_t times = sizeof(ElementControlBlock) / 16; uint32_t times = sizeof(ChunkControlBlock) / 16;
return (remains ? times + 1 : times) * 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; return (remains ? times + 1 : times) * 16;
} }
MemoryChunk::MemoryChunk(ElementControlBlock* access_bind) MemoryChunk::MemoryChunk(ChunkControlBlock* access_bind)
: data_ptr((ElementControlBlock*)access_bind) {} : data_ptr((ChunkControlBlock*)access_bind) {}
uint16_t MemoryChunk::typeSize() const uint16_t MemoryChunk::typeSize() const
{ {
@ -122,7 +122,7 @@ void MemoryChunk::accessUpdate(uint64_t time_usec)
data_ptr->page_refer->accessRecord(time_usec); data_ptr->page_refer->accessRecord(time_usec);
} }
bool MemoryChunk::isActived(ElementControlBlock* refer) bool MemoryChunk::isActived(ChunkControlBlock* refer)
{ {
refer->page_refer->lock(); refer->page_refer->lock();
auto mark = refer->refer_count; auto mark = refer->refer_count;

View File

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