update chunk-nm
This commit is contained in:
parent
f0fdd7708e
commit
701db4d98d
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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; // 最近访问时间点,lsb:us
|
uint64_t curr_access_usec = 0; // 最近访问时间点,lsb:us
|
||||||
|
|
||||||
|
|
@ -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>
|
||||||
/// 提取关联元素尺寸
|
/// 提取关联元素尺寸
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue