|
|
|
@ -85,6 +85,15 @@ bool ShouldSplit(const Block *block, size_t size) {
|
|
|
|
|
return static_cast<double>(size) <= (static_cast<double>(block->size) * kSplitThreshold);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IncreaseCount(std::map<size_t, size_t> &count, size_t size) {
|
|
|
|
|
auto it = count.find(size);
|
|
|
|
|
if (it != count.end()) {
|
|
|
|
|
it->second++;
|
|
|
|
|
} else {
|
|
|
|
|
count.emplace(size, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CachingAllocator::CachingAllocator(rtMemType_t memory_type) : memory_type_(memory_type), memory_allocator_(nullptr) {
|
|
|
|
|
for (uint32_t i = 0; i < kNumBins; ++i) {
|
|
|
|
|
free_block_bins_[i] = nullptr;
|
|
|
|
@ -116,6 +125,7 @@ Status CachingAllocator::Initialize(uint32_t device_id) {
|
|
|
|
|
|
|
|
|
|
void CachingAllocator::Finalize(uint32_t device_id) {
|
|
|
|
|
GELOGI("Device id %u", device_id);
|
|
|
|
|
PrintStatics();
|
|
|
|
|
FreeBlocks();
|
|
|
|
|
FreeBlockBins();
|
|
|
|
|
}
|
|
|
|
@ -205,8 +215,7 @@ BlockBin *CachingAllocator::GetBlockBin(size_t size) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Block *CachingAllocator::FindFreeBlock(size_t size, uint8_t *org_ptr, uint32_t device_id) {
|
|
|
|
|
// org_ptr - 1, try to find ptr same as org_ptr
|
|
|
|
|
Block key(device_id, size, (org_ptr == nullptr ? nullptr : org_ptr - 1));
|
|
|
|
|
Block key(device_id, size, org_ptr);
|
|
|
|
|
BlockBin *bin = GetBlockBin(size);
|
|
|
|
|
if (bin == nullptr) {
|
|
|
|
|
GELOGE(ge::FAILED, "Get block bin failed size = %zu", size);
|
|
|
|
@ -262,18 +271,22 @@ Status CachingAllocator::TryExtendCache(size_t size, uint32_t device_id) {
|
|
|
|
|
auto memory_addr = memory_allocator_->MallocMemory(purpose, memory_size, device_id);
|
|
|
|
|
// try to free caches and malloc again when malloc memory failed
|
|
|
|
|
if (memory_addr == nullptr) {
|
|
|
|
|
FreeCachedBlocks();
|
|
|
|
|
size_t free_cached_memory_size = FreeCachedBlocks();
|
|
|
|
|
memory_addr = memory_allocator_->MallocMemory(purpose, memory_size, device_id);
|
|
|
|
|
if (memory_addr == nullptr) {
|
|
|
|
|
GELOGE(ge::FAILED, "TryExtendCache failed, no enough memory for size = %zu, device_id = %u", memory_size,
|
|
|
|
|
device_id);
|
|
|
|
|
return ge::FAILED;
|
|
|
|
|
}
|
|
|
|
|
GELOGT(TRACE_RUNNING, "Try to free cached memory size:%zu and malloc memory size:%zu success.",
|
|
|
|
|
free_cached_memory_size, memory_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (AddToBlockBin(memory_addr, memory_size, device_id) != ge::SUCCESS) {
|
|
|
|
|
(void)memory_allocator_->FreeMemory(memory_addr);
|
|
|
|
|
return ge::FAILED;
|
|
|
|
|
}
|
|
|
|
|
PrintStatics();
|
|
|
|
|
return ge::SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -294,13 +307,15 @@ Status CachingAllocator::AddToBlockBin(uint8_t *ptr, size_t size, uint32_t devic
|
|
|
|
|
block->size = size;
|
|
|
|
|
|
|
|
|
|
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
|
|
|
IncreaseCount(malloced_memory_, block->size);
|
|
|
|
|
bin->insert(block);
|
|
|
|
|
return ge::SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CachingAllocator::FreeCachedBlocks() {
|
|
|
|
|
size_t CachingAllocator::FreeCachedBlocks() {
|
|
|
|
|
GELOGI("Free cached blocks");
|
|
|
|
|
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
|
|
|
size_t free_cached_memory_size = 0;
|
|
|
|
|
for (uint32_t i = 0; i < kNumBins; ++i) {
|
|
|
|
|
auto pool = free_block_bins_[i];
|
|
|
|
|
if (pool == nullptr) {
|
|
|
|
@ -311,6 +326,14 @@ void CachingAllocator::FreeCachedBlocks() {
|
|
|
|
|
// free block memory that has not been split
|
|
|
|
|
if ((block != nullptr) && (block->ptr != nullptr) && (block->prev == nullptr) && (block->next == nullptr) &&
|
|
|
|
|
(memory_allocator_->FreeMemory(block->ptr) == ge::SUCCESS)) {
|
|
|
|
|
auto itcount = malloced_memory_.find(block->size);
|
|
|
|
|
free_cached_memory_size += block->size;
|
|
|
|
|
if (itcount != malloced_memory_.end()) {
|
|
|
|
|
itcount->second--;
|
|
|
|
|
if (itcount->second == 0) {
|
|
|
|
|
malloced_memory_.erase(itcount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pool->erase(it++);
|
|
|
|
|
delete block;
|
|
|
|
|
continue;
|
|
|
|
@ -318,6 +341,7 @@ void CachingAllocator::FreeCachedBlocks() {
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return free_cached_memory_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CachingAllocator::FreeBlocks() {
|
|
|
|
@ -328,8 +352,7 @@ void CachingAllocator::FreeBlocks() {
|
|
|
|
|
FreeBlock(it.second);
|
|
|
|
|
}
|
|
|
|
|
allocated_blocks_.clear();
|
|
|
|
|
|
|
|
|
|
FreeCachedBlocks();
|
|
|
|
|
(void) FreeCachedBlocks();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CachingAllocator::FreeBlockBins() {
|
|
|
|
@ -342,4 +365,60 @@ void CachingAllocator::FreeBlockBins() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintCount(std::map<size_t, size_t> &count, const std::string &name, size_t total_size, size_t total_count) {
|
|
|
|
|
GELOGI("%6s total[size:%10zu count:%10zu]", name.c_str(), total_size, total_count);
|
|
|
|
|
for (auto &it : count) {
|
|
|
|
|
GELOGI(" |- block[size:%10zu count:%10zu]", it.first, it.second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CachingAllocator::PrintStatics() {
|
|
|
|
|
if (!IsLogEnable(GE_MODULE_NAME, DLOG_INFO)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
size_t total_using_size = 0;
|
|
|
|
|
size_t total_using_count = 0;
|
|
|
|
|
size_t total_free_size = 0;
|
|
|
|
|
size_t total_free_count = 0;
|
|
|
|
|
size_t total_malloc_size = 0;
|
|
|
|
|
size_t total_malloc_count = 0;
|
|
|
|
|
std::map<size_t, size_t> using_block;
|
|
|
|
|
std::map<size_t, size_t> free_block;
|
|
|
|
|
std::map<size_t, size_t> malloc_block;
|
|
|
|
|
do {
|
|
|
|
|
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
|
|
|
for (uint32_t i = 0; i < kNumBins; ++i) {
|
|
|
|
|
auto pool = free_block_bins_[i];
|
|
|
|
|
if (pool == nullptr) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (auto it = pool->begin(); it != pool->end(); ++it) {
|
|
|
|
|
if ((*it) != nullptr) {
|
|
|
|
|
total_free_size += (*it)->size;
|
|
|
|
|
IncreaseCount(free_block, (*it)->size);
|
|
|
|
|
total_free_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto &it : allocated_blocks_) {
|
|
|
|
|
if (it.second != nullptr) {
|
|
|
|
|
total_using_size += it.second->size;
|
|
|
|
|
IncreaseCount(using_block, it.second->size);
|
|
|
|
|
total_using_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto &it : malloced_memory_) {
|
|
|
|
|
total_malloc_size += it.first * it.second;
|
|
|
|
|
total_malloc_count += it.second;
|
|
|
|
|
malloc_block[it.first] = it.second;
|
|
|
|
|
}
|
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
|
|
PrintCount(malloc_block, "Malloc", total_malloc_size, total_malloc_count);
|
|
|
|
|
PrintCount(using_block, "Using", total_using_size, total_using_count);
|
|
|
|
|
PrintCount(free_block, "Free", total_free_size, total_free_count);
|
|
|
|
|
}
|
|
|
|
|
} // namespace ge
|
|
|
|
|