Browse Source

fix(src/core): fix pushdown alloc_result inconsistent when run for many time

GitOrigin-RevId: 3b087203a1
master
Megvii Engine Team 2 years ago
parent
commit
f287501eb2
2 changed files with 38 additions and 12 deletions
  1. +26
    -12
      src/core/impl/graph/var_node_mem_mgr/static_mem_alloc/pushdown.cpp
  2. +12
    -0
      src/core/test/static_mem_alloc.cpp

+ 26
- 12
src/core/impl/graph/var_node_mem_mgr/static_mem_alloc/pushdown.cpp View File

@@ -51,7 +51,7 @@ private:


std::list<MemBlock> m_mem_block; std::list<MemBlock> m_mem_block;
using MemBlockIter = decltype(m_mem_block.begin()); using MemBlockIter = decltype(m_mem_block.begin());
std::set<FreeBlockBySizeItem> m_free_by_size;
std::multiset<FreeBlockBySizeItem> m_free_by_size;
using FreeBySizeIter = decltype(m_free_by_size.begin()); using FreeBySizeIter = decltype(m_free_by_size.begin());


struct MemBlock { struct MemBlock {
@@ -67,6 +67,8 @@ private:
*/ */
size_t size = 0; size_t size = 0;


size_t time_end = -1;

/*! /*!
* FreeBlockBySizeItem iter for unallocated intervals; should be * FreeBlockBySizeItem iter for unallocated intervals; should be
* accessed only when *interval* is nullptr * accessed only when *interval* is nullptr
@@ -77,6 +79,13 @@ private:


bool allocated() const { return interval; } bool allocated() const { return interval; }


bool operator<(const MemBlock& rhs) {
if (time_end != (size_t)(-1) && rhs.time_end != (size_t)(-1))
return time_end > rhs.time_end;
else
return time_end != (size_t)(-1) || this < &rhs;
}

private: private:
IncompleteObjStorageMock<FreeBySizeIter, std::set<int>::iterator> m_fs_iter; IncompleteObjStorageMock<FreeBySizeIter, std::set<int>::iterator> m_fs_iter;
}; };
@@ -99,7 +108,7 @@ private:
return size < rhs.size || return size < rhs.size ||
(size == rhs.size && (size == rhs.size &&
(!blk_iter_valid || (!blk_iter_valid ||
(rhs.blk_iter_valid && &*blk_iter < &*rhs.blk_iter)));
(rhs.blk_iter_valid && *blk_iter < *rhs.blk_iter)));
} }
}; };


@@ -114,14 +123,14 @@ private:
* \param size size of free block; if it is zero, no insertion would be * \param size size of free block; if it is zero, no insertion would be
* performed * performed
*/ */
void insert_free_blk_before(MemBlockIter pos, size_t size);
void insert_free_blk_before(MemBlockIter pos, size_t size, size_t time_end);


/*! /*!
* \brief insert a free MemBlock after given position * \brief insert a free MemBlock after given position
*/ */
void insert_free_blk_after(MemBlockIter pos, size_t size) {
void insert_free_blk_after(MemBlockIter pos, size_t size, size_t time_end) {
mgb_assert(pos != m_mem_block.end()); mgb_assert(pos != m_mem_block.end());
return insert_free_blk_before(++pos, size);
return insert_free_blk_before(++pos, size, time_end);
} }
}; };
StaticMemAllocPushdown::BestfitPrealloc::MemBlock::~MemBlock() = default; StaticMemAllocPushdown::BestfitPrealloc::MemBlock::~MemBlock() = default;
@@ -176,6 +185,7 @@ PREALLOC_MEM_TR(AllocResult)::alloc(Interval* interval) {
--iter; --iter;
mgb_assert(iter->size < interval->size); mgb_assert(iter->size < interval->size);
iter->blk_iter->size = interval->size; iter->blk_iter->size = interval->size;
iter->blk_iter->time_end = interval->time_end;
} }
auto blkpos = iter->blk_iter; auto blkpos = iter->blk_iter;
m_free_by_size.erase(iter); m_free_by_size.erase(iter);
@@ -185,7 +195,7 @@ PREALLOC_MEM_TR(AllocResult)::alloc(Interval* interval) {
auto free_size = safe_sub(blkpos->size, interval->size); auto free_size = safe_sub(blkpos->size, interval->size);
// mark allocated result before inserting block // mark allocated result before inserting block
blkpos->interval = interval; blkpos->interval = interval;
insert_free_blk_after(blkpos, free_size);
insert_free_blk_after(blkpos, free_size, interval->time_end);
return make_alloc_result(blkpos, interval); return make_alloc_result(blkpos, interval);
} }


@@ -193,9 +203,10 @@ PREALLOC_MEM_TR(AllocResult)::alloc_overwrite(
AllocResult& dest, size_t offset, Interval* interval) { AllocResult& dest, size_t offset, Interval* interval) {
auto iter = dest.m_iter; auto iter = dest.m_iter;
mgb_assert(dest.m_valid && iter->allocated()); mgb_assert(dest.m_valid && iter->allocated());
insert_free_blk_before(iter, offset);
insert_free_blk_before(iter, offset, iter->interval->time_end);
insert_free_blk_after( insert_free_blk_after(
iter, safe_sub(iter->interval->size, offset + interval->size));
iter, safe_sub(iter->interval->size, offset + interval->size),
iter->interval->time_end);
dest.m_valid = false; dest.m_valid = false;
return make_alloc_result(iter, interval); return make_alloc_result(iter, interval);
} }
@@ -204,6 +215,7 @@ PREALLOC_MEM_TR(AllocResult)::make_alloc_result(MemBlockIter pos, Interval* inte
pos->interval = interval; pos->interval = interval;
pos->fsiter() = {}; pos->fsiter() = {};
pos->size = 0; pos->size = 0;
pos->time_end = interval->time_end;


Interval *iprev = nullptr, *inext = nullptr; Interval *iprev = nullptr, *inext = nullptr;
// find prev allocated interval // find prev allocated interval
@@ -241,13 +253,15 @@ PREALLOC_MEM(void)::free(AllocResult& alloc_rst) {
mgb_assert(iter->allocated()); mgb_assert(iter->allocated());
auto size = iter->interval->size; auto size = iter->interval->size;
auto pos = iter; auto pos = iter;
auto time_end = iter->time_end;
++pos; ++pos;
m_mem_block.erase(iter); m_mem_block.erase(iter);
alloc_rst.m_valid = false; alloc_rst.m_valid = false;
insert_free_blk_before(pos, size);
insert_free_blk_before(pos, size, time_end);
} }


PREALLOC_MEM(void)::insert_free_blk_before(MemBlockIter pos, size_t size) {
PREALLOC_MEM(void)::insert_free_blk_before(
MemBlockIter pos, size_t size, size_t time_end) {
auto rm = [this](MemBlockIter it) { auto rm = [this](MemBlockIter it) {
mgb_assert(!it->allocated()); mgb_assert(!it->allocated());
m_free_by_size.erase(it->fsiter()); m_free_by_size.erase(it->fsiter());
@@ -278,10 +292,10 @@ PREALLOC_MEM(void)::insert_free_blk_before(MemBlockIter pos, size_t size) {
return; return;


auto blk_iter = m_mem_block.insert(pos, MemBlock()); auto blk_iter = m_mem_block.insert(pos, MemBlock());
blk_iter->time_end = time_end;
auto rst_s = m_free_by_size.insert({size, blk_iter}); auto rst_s = m_free_by_size.insert({size, blk_iter});
mgb_assert(rst_s.second);
blk_iter->size = size; blk_iter->size = size;
blk_iter->fsiter() = rst_s.first;
blk_iter->fsiter() = rst_s;
} }


#undef PREALLOC_MEM #undef PREALLOC_MEM


+ 12
- 0
src/core/test/static_mem_alloc.cpp View File

@@ -222,6 +222,18 @@ TEST(TestStaticMemAllocAlgo, PushdownChain) {
ASSERT_EQ(NR + NR - 1, allocator->tot_alloc()); ASSERT_EQ(NR + NR - 1, allocator->tot_alloc());
} }


TEST(TestStaticMemAllocAlgo, PushdownConsistence) {
for (size_t run_nr = 0; run_nr < 500; ++run_nr) {
auto allocator = StaticMemAlloc::make(StaticMemAlloc::AllocatorAlgo::PUSHDOWN);
constexpr size_t NR = 100;
for (size_t i = 0; i < NR; ++i)
allocator->add(i, i + 2, i + 1, makeuk(i));

allocator->solve();
ASSERT_EQ(NR + NR - 1, allocator->tot_alloc_lower_bound());
ASSERT_EQ(NR + NR - 1, allocator->tot_alloc());
}
}
#endif // WIN32 #endif // WIN32


// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

Loading…
Cancel
Save