应用层内存管理及调试的学习-----(3)

既然我们想做比较靠谱的性能测试,首先要知道如何准确测量一段代码的执行时间

此时,寄出了自己的windows 核心编程–7.6 有对于线程执行时间的获取的描述

#include <windows.h>
#include <assert.h>
#include "CElapsedMicroseconds.h"

static BOOL g_bInitFrequncy = QueryPerformanceFrequency(&CElapsedMicroseconds::m_Frequency);
CElapsedMicroseconds::CElapsedMicroseconds()
{
	assert(g_bInitFrequncy);

	// 避免被中断
	SetProcessPriorityBoost(GetCurrentProcess(), true);

	assert(QueryPerformanceCounter(&m_StartingTime));
}

LARGE_INTEGER CElapsedMicroseconds::GetElapsedMicroseconds()
{
	LARGE_INTEGER EndingTime = {};
	LARGE_INTEGER ElapsedMicroseconds = {};
	assert(QueryPerformanceCounter(&EndingTime));
	ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - m_StartingTime.QuadPart;
	ElapsedMicroseconds.QuadPart *= 1000000;
	ElapsedMicroseconds.QuadPart /= m_Frequency.QuadPart;

	m_StartingTime = EndingTime;	// 更新最后的执行时间

	return ElapsedMicroseconds;
}

CElapsedMicroseconds::~CElapsedMicroseconds()
{
	SetProcessPriorityBoost(GetCurrentProcess(), false);
}

这个文章,尝试梳理一下定制内存管理器的必要性以及测试内存allocator 的方法

  • 必要性
  1. 当我们无脑的调用new 和 delete,或者malloc free 的时候,通过之前的代码看到,显然使用的是系统默认堆.
  2. 而多线程环境下,如果全部程序都使用这种无脑的方法,一个是需求种类复杂,大小导致,长时间执行必然导致内存碎片,内存申请和释放都将消耗很长的时间
  3. 另一方面,多线程环境下,对于同一个堆的同步访问将导致大量的时间
  4. 长时间运行的系统,分配模式需要保持低碎片,否则时间越久,碎片将导致系统无法继续执行。
  5. 系统调用,进内核、出内核,将消耗大量时间
  • 优化allocator 的方向
  • 参考https://www.codeproject.com/Articles/1083210/An-Efficient-Cplusplus-Fixed-Block-Memory-Allocato
  1. Heap blocks
    全新块的申请是new 从process heap 中申请的,free 的时候,放入了free-list,再次申请的时候悠闲从free-list 申请,没有再去new(后进先出,提高重复利用率)
  2. Heap pool
    通过 new 从process heap 申请一个单独的池,之后通过这个pool 申请内存
  3. Static pool
    使用一个静态的内存池,通常是一块比较大的静态内存,来存储所有的内存块。该静态内存池后续被用来申请内存。

heap pool 和 static pool 模式提供了固定申请执行时间。heap blocks可能有额外的查找和new 操作。

  • 阅读了网络上一些内存管理器的文章后发现,大部分的实现,都是将内存申请时限为:
union{
void* next;
char pData[size];
}

通过上面的这种方式,实现了memory pool 的概念,再加上一些锁,优化的最佳的实现也就是锁的实现。

  • bitmap 的方法表达内存是否被占用,申请和释放都使用比较短的时间

  • 通过增加heap 的个数,一方面减少多线程申请和释放的竞争,另一方面,减少内存相互的影响,提高多线程环境下申请和释放的速度。

优化的具体方法,放在下一届,下面先想一下测试方法和用例,否则写出来也不知道好坏

内存测试框架的要求,想要测试的alloctor需要实现特定的内存申请接口,统一测试方法

接口设计的要求:

  1. 支持多线程环境测试
  2. 支持测试原生的malloc free,new delete 测试
  3. 支持内存碎片类型的申请释放操作的测试
  4. 支持固定大小内存块的频繁申请释放(可能特定场景就会是这种,看哪种实现效率高)
  5. 单进程测试单独的小功能, 避免初始地址空间不同带来的影响
  6. 测试进程都以最高优先级运行,保证测试的可信度
  7. 申请和释放分别计时
  8. 数组类型的申请、释放操作计时
  9. 多次执行取平均
  10. 对比boost 的实现
  11. 是否需要在非必要的时候,释放空闲的整块的大块的内存

下一个开始写代码了

发布了93 篇原创文章 · 获赞 13 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_18218335/article/details/102225367