內存池與C++實現

https://blog.csdn.net/u010183728/article/details/81531392

 

1. 內存池設計

1.1 目的

在給定的內存buffer上建立內存管理機制,根據用戶需求從該buffer上分配內存或者將已經分配的內存釋放回buffer中。

1.2 要求

儘量減少內存碎片,平均效率高於C語言的malloc和free。

1.3 設計思路

將buffer分爲四部分,第1部分是mem_pool結構體;第2部分是內存映射表;第3部分是內存chunk結構體緩衝區;第4部分是實際可分配的內存區。整個buffer結構圖如圖1所示:

圖1 內存buffer結構圖

圖1 內存buffer結構圖

第1部分的作用是可以通過該mem_pool結構體控制整個內存池。

第2部分的作用是記錄第4部分,即實際可分配的內存區的使用情況。表中的每一個單元表示一個固定大小的內存塊(block),多個連續的block組成一個chunk,每個block的詳細結構如圖2所示:

圖2 memory block結構圖

圖2 memory block結構圖

其中count表示該block後面的與該block同屬於一個chunk的blokc的個數,start表示該block所在的chunk的起始block索引。其實start這個域只有在每個chunk的最後一個block中才會用到(用於從當前chunk尋找前一個chunk的起始位置),而pmem_chunk則是一個指針,指向一個mem_chunk結構體。任意一塊大小的內存都會被取向上整到block大小的整數倍。

第3部分是一個mem_chunk pool,其作用是存儲整個程序可用的mem_chunk結構體。mem_chunk pool中的mem_chunk被組織成雙向鏈表結構(快速插入和刪除)。每個mem_chunk結構圖如圖3所示:

圖3 memory chunk結構圖

圖3 memory chunk結構圖

其中pmem_block指向該chunk在內存映射表中的位置,others表示其他一些域,不同的實現對應該域的內容略有不同。

第4部分就是實際可以被分配給用戶的內存。

整個內存池管理程序除了這四部分外,還有一個重要的內容就是memory chunk set。雖然其中的每個元素都來自mem_chunk pool,但是它與mem_chunk pool的不同之處在於其中的每個memory chunk中記錄了當前可用的一塊內存的相關信息。而mem_chunk pool中的memory chunk的內容是無定以的。可以這樣理解mem_chunk pool與memory chunk set:mem_chunk pool是爲memory chunk set分配內存的“內存池”,只是該“內存池”每次分配的內存大小是固定的,爲mem_chunk結構體的大小。內存池程序主要是通過搜索這個memory chunk set來獲取可被分配的內存。在memory chunk set上建立不同的數據結構就構成了不同的內存池實現方法,同時也導致了不同的搜索效率,直接影響內存池的性能,本文稍後會介紹兩種內存池的實現。

1.4 內存池管理程序運行過程

  • 初始化:內存映射表中只有一塊可用的內存信息,大小爲內存池中所有可用的內存。從memory chunk pool中分配一個mem_chunk,使其指向內存映射表中的第一個block,並根據具體的內存池實現方式填充mem_chunk中的其他域,然後將該mem_chunk添加到memory chunk set中。
  • 申請內存:當用戶申請一塊內存時,首先在memory chunk set中查找合適的內存塊。如果找到符合要求的內存塊,就在內存映射表中找到相應的chunk,並修改chunk中相應block結構體的內容,然後根據修改後的chunk修改memory chunk set中chunk的內容,最後返回分配內存的起始地址;否則返回NULL。
  • 釋放內存:當用戶釋放一塊內存時,首先根據這塊內存的起始地址找到其在內存映射表中對應的chunk,然後嘗試將該chunk和與其相鄰的chunk合併,修改chunk中相應block的內容並修改memory chunk set中相應chunk的內容或者向memory chunk set加入新的mem_chunk(這種情況在不能合併內存是發生)。

1.5 減少內存碎片

本文設計的方法只能在一定程度上減少內存碎片,並不能徹底消除內存碎片。具體方法如下:

在用戶釋放內存時,嘗試將該內存與其相鄰的內存合併。如果其相鄰內存爲未分配內存則合併成功,合併後作爲一整塊內存使用;如火其相鄰內存爲已分配內存則不能合併,該釋放的內存塊作爲一個獨立的內存塊被使用。

2 內存池實現-鏈表結構

2.1 性能分析

鏈表結構的內存池實現是指將memory chunk set實現爲雙鏈表結構。這種方法的優缺點如下:

優點:釋放內存很快,O(1)複雜度。

缺點:分配內存較慢,O(n)複雜度。

2.2 內存池運行狀態轉移圖

綠色表示未使用的內存,紅色表示已經使用的內存。其中每個block表示64B,這個值可以根據具體需要設定。

  • 初始化

圖4 內存池初始化狀態

圖4 內存池初始化狀態

  • 申請內存

圖5 第1次申請128B內存後

圖5 第1次申請128B內存後

圖6 第n次申請、釋放內存後

圖6 第n次申請、釋放內存後

  • 釋放內存

 

圖7 釋放64B內存前後

圖7 釋放64B內存前後

3 內存池實現-大頂堆結構

3.1 性能分析

 

大頂堆結構的內存池實現是指將memory chunk set實現爲大頂堆結構。這種方法的優缺點如下:

優點:降低了分配內存的時間複雜度,O(log(n))。

缺點:增加了釋放內存的時間複雜度,O(log(n))。

3.2 內存池運行狀態轉移圖

綠色表示未使用的內存,紅色表示已經使用的內存。其中每個block表示64B,這個值可以根據具體需要設定。

  • 初始化

圖8 內存池初始化狀態

圖8 內存池初始化狀態

  • 申請內存

圖9 第1次申請128B內存後

圖9 第1次申請128B內存後

圖10 第n次申請、釋放內存後

圖10 第n次申請、釋放內存後

  • 釋放內存

圖11 釋放64B內存前後

圖11 釋放64B內存前後

4 性能測試

  • 測試對象:C語言的malloc、free和本文的兩種內存池(大小爲500M,實際可分配內存爲310M)。
  • 測試指標:執行n=2000次隨機分配、釋放隨機大小內存(範圍爲64B~1024B)的時間比。
  • 測試方法1:

(1) 生成n個隨機數,大小在64~1024之間,用於表示n個要分配的內存大小;

(2) 生成n個隨機數,取值 爲0或者1,表示每次分配內存後緊接着是否釋放內存;

(3) 測量C語言的malloc、free和本文兩種內存池執行n次隨機分配、釋放隨機大小內存的時間比ratio;

(4) 重複(3)m=200次,記錄每次活動的ratio,並繪製相應的曲線。

  • 測試方法2:

(1) 生成n個隨機數,大小在a~b之間(初始值a=64,b=1024),用於表示n個要分配的內存大小;

(2) 測量C語言的malloc、free和本文兩種內存池執行n次分配、釋放隨機大小內存的時間比ratio;

(3) 重複(2)m=512次,每次分配的內存容量的範圍比前一次大1024B,記錄每次獲得的ratio,並繪製相應曲線。

4.1 性能測試結果-鏈表結果內存池

圖12 鏈表結構內存池性能測試結果1

圖12 鏈表結構內存池性能測試結果1

鏈表結構內存池性能測試結果2

圖13 鏈表結構內存池性能測試結果2

4.2 性能測試結果-大頂堆結構內存池

圖14 大頂堆內存池性能測試結果1

圖14 大頂堆內存池性能測試結果1

圖15 大頂堆內存池性能測試結果2

圖15 大頂堆內存池性能測試結果2

4.3 性能比較

圖16 兩種內存池性能測試結果比較1

圖16 兩種內存池性能測試結果比較1

圖17 兩種內存池性能測試結果比較2

圖17 兩種內存池性能測試結果比較2

5 結論

從上面的內存池性能測試結果中可以看出,相比C語言的malloc和free,內存池使得用戶分配內存和釋放內存的效率有了較大的提高,這一優勢尤其分配較大快的內存時體現的尤爲突出。

同時也可以看出大頂堆結夠的內存池的性能並不比鏈表結構的內存池性能高,反而低於鏈表結構內存池的性能。這再一次表明O(log(n))優於O(n)是有條件的。當然,本文的測試具有一定的侷限性,也許在其他的測試案例中大頂堆結構的內存池性能會超越鏈表結構的內存池。

附:源代碼

鏈表結構內存池:

MemoryPool.h


 
  1. #ifndef _MEMORYPOOL_H

  2. #define _MEMORYPOOL_H

  3. #include <stdlib.h>

  4. #define MINUNITSIZE 64

  5. #define ADDR_ALIGN 8

  6. #define SIZE_ALIGN MINUNITSIZE

  7. struct memory_chunk;

  8. typedef struct memory_block

  9. {

  10. size_t count;

  11. size_t start;

  12. memory_chunk* pmem_chunk;

  13. }memory_block;

  14. // 可用的內存塊結構體

  15. typedef struct memory_chunk

  16. {

  17. memory_block* pfree_mem_addr;

  18. memory_chunk* pre;

  19. memory_chunk* next;

  20. }memory_chunk;

  21. // 內存池結構體

  22. typedef struct MEMORYPOOL

  23. {

  24. void *memory;

  25. size_t size;

  26. memory_block* pmem_map;

  27. memory_chunk* pfree_mem_chunk;

  28. memory_chunk* pfree_mem_chunk_pool;

  29. size_t mem_used_size; // 記錄內存池中已經分配給用戶的內存的大小

  30. size_t mem_map_pool_count; // 記錄鏈表單元緩衝池中剩餘的單元的個數,個數爲0時不能分配單元給pfree_mem_chunk

  31. size_t free_mem_chunk_count; // 記錄 pfree_mem_chunk鏈表中的單元個數

  32. size_t mem_map_unit_count; //

  33. size_t mem_block_count; // 一個 mem_unit 大小爲 MINUNITSIZE

  34. }MEMORYPOOL, *PMEMORYPOOL;

  35. /************************************************************************/

  36. /* 生成內存池

  37. * pBuf: 給定的內存buffer起始地址

  38. * sBufSize: 給定的內存buffer大小

  39. * 返回生成的內存池指針

  40. /************************************************************************/

  41. PMEMORYPOOL CreateMemoryPool(void* pBuf, size_t sBufSize);

  42. /************************************************************************/

  43. /* 暫時沒用

  44. /************************************************************************/

  45. void ReleaseMemoryPool(PMEMORYPOOL* ppMem) ;

  46. /************************************************************************/

  47. /* 從內存池中分配指定大小的內存

  48. * pMem: 內存池 指針

  49. * sMemorySize: 要分配的內存大小

  50. * 成功時返回分配的內存起始地址,失敗返回NULL

  51. /************************************************************************/

  52. void* GetMemory(size_t sMemorySize, PMEMORYPOOL pMem) ;

  53.  
  54. /************************************************************************/

  55. /* 從內存池中釋放申請到的內存

  56. * pMem:內存池指針

  57. * ptrMemoryBlock:申請到的內存起始地址

  58. /************************************************************************/

  59. void FreeMemory(void *ptrMemoryBlock, PMEMORYPOOL pMem) ;

  60.  
  61. #endif //_MEMORYPOOL_H

MemoryPool.cpp


 
  1. #include "stdafx.h"

  2. #include <memory.h>

  3. #include "MemoryPool.h"

  4. /************************************************************************/

  5. /* 內存池起始地址對齊到ADDR_ALIGN字節

  6. /************************************************************************/

  7. size_t check_align_addr(void*& pBuf)

  8. {

  9. size_t align = 0;

  10. size_t addr = (int)pBuf;

  11. align = (ADDR_ALIGN - addr % ADDR_ALIGN) % ADDR_ALIGN;

  12. pBuf = (char*)pBuf + align;

  13. return align;

  14. }

  15. /************************************************************************/

  16. /* 內存block大小對齊到MINUNITSIZE字節

  17. /************************************************************************/

  18. size_t check_align_block(size_t size)

  19. {

  20. size_t align = size % MINUNITSIZE;

  21.  
  22. return size - align;

  23. }

  24. /************************************************************************/

  25. /* 分配內存大小對齊到SIZE_ALIGN字節

  26. /************************************************************************/

  27. size_t check_align_size(size_t size)

  28. {

  29. size = (size + SIZE_ALIGN - 1) / SIZE_ALIGN * SIZE_ALIGN;

  30. return size;

  31. }

  32. /************************************************************************/

  33. /* 以下是鏈表相關操作

  34. /************************************************************************/

  35. memory_chunk* create_list(memory_chunk* pool, size_t count)

  36. {

  37. if (!pool)

  38. {

  39. return NULL;

  40. }

  41. memory_chunk* head = NULL;

  42. for (size_t i = 0; i < count; i++)

  43. {

  44. pool->pre = NULL;

  45. pool->next = head;

  46. if (head != NULL)

  47. {

  48. head->pre = pool;

  49. }

  50. head = pool;

  51. pool++;

  52. }

  53. return head;

  54. }

  55. memory_chunk* front_pop(memory_chunk*& pool)

  56. {

  57. if (!pool)

  58. {

  59. return NULL;

  60. }

  61. memory_chunk* tmp = pool;

  62. pool = tmp->next;

  63. pool->pre = NULL;

  64. return tmp;

  65. }

  66. void push_back(memory_chunk*& head, memory_chunk* element)

  67. {

  68. if (head == NULL)

  69. {

  70. head = element;

  71. head->pre = element;

  72. head->next = element;

  73. return;

  74. }

  75. head->pre->next = element;

  76. element->pre = head->pre;

  77. head->pre = element;

  78. element->next = head;

  79. }

  80. void push_front(memory_chunk*& head, memory_chunk* element)

  81. {

  82. element->pre = NULL;

  83. element->next = head;

  84. if (head != NULL)

  85. {

  86. head->pre = element;

  87. }

  88. head = element;

  89. }

  90. void delete_chunk(memory_chunk*& head, memory_chunk* element)

  91. {

  92. // 在雙循環鏈表中刪除元素

  93. if (element == NULL)

  94. {

  95. return;

  96. }

  97. // element爲鏈表頭

  98. else if (element == head)

  99. {

  100. // 鏈表只有一個元素

  101. if (head->pre == head)

  102. {

  103. head = NULL;

  104. }

  105. else

  106. {

  107. head = element->next;

  108. head->pre = element->pre;

  109. head->pre->next = head;

  110. }

  111. }

  112. // element爲鏈表尾

  113. else if (element->next == head)

  114. {

  115. head->pre = element->pre;

  116. element->pre->next = head;

  117. }

  118. else

  119. {

  120. element->pre->next = element->next;

  121. element->next->pre = element->pre;

  122. }

  123. element->pre = NULL;

  124. element->next = NULL;

  125. }

  126. /************************************************************************/

  127. /* 內存映射表中的索引轉化爲內存起始地址

  128. /************************************************************************/

  129. void* index2addr(PMEMORYPOOL mem_pool, size_t index)

  130. {

  131. char* p = (char*)(mem_pool->memory);

  132. void* ret = (void*)(p + index *MINUNITSIZE);

  133.  
  134. return ret;

  135. }

  136. /************************************************************************/

  137. /* 內存起始地址轉化爲內存映射表中的索引

  138. /************************************************************************/

  139. size_t addr2index(PMEMORYPOOL mem_pool, void* addr)

  140. {

  141. char* start = (char*)(mem_pool->memory);

  142. char* p = (char*)addr;

  143. size_t index = (p - start) / MINUNITSIZE;

  144. return index;

  145. }

  146. /************************************************************************/

  147. /* 生成內存池

  148. * pBuf: 給定的內存buffer起始地址

  149. * sBufSize: 給定的內存buffer大小

  150. * 返回生成的內存池指針

  151. /************************************************************************/

  152. PMEMORYPOOL CreateMemoryPool(void* pBuf, size_t sBufSize)

  153. {

  154. memset(pBuf, 0, sBufSize);

  155. PMEMORYPOOL mem_pool = (PMEMORYPOOL)pBuf;

  156. // 計算需要多少memory map單元格

  157. size_t mem_pool_struct_size = sizeof(MEMORYPOOL);

  158. mem_pool->mem_map_pool_count = (sBufSize - mem_pool_struct_size + MINUNITSIZE - 1) / MINUNITSIZE;

  159. mem_pool->mem_map_unit_count = (sBufSize - mem_pool_struct_size + MINUNITSIZE - 1) / MINUNITSIZE;

  160. mem_pool->pmem_map = (memory_block*)((char*)pBuf + mem_pool_struct_size);

  161. mem_pool->pfree_mem_chunk_pool = (memory_chunk*)((char*)pBuf + mem_pool_struct_size + sizeof(memory_block) * mem_pool->mem_map_unit_count);

  162.  
  163. mem_pool->memory = (char*)pBuf + mem_pool_struct_size+ sizeof(memory_block) * mem_pool->mem_map_unit_count + sizeof(memory_chunk) * mem_pool->mem_map_pool_count;

  164. mem_pool->size = sBufSize - mem_pool_struct_size - sizeof(memory_block) * mem_pool->mem_map_unit_count - sizeof(memory_chunk) * mem_pool->mem_map_pool_count;

  165. size_t align = check_align_addr(mem_pool->memory);

  166. mem_pool->size -= align;

  167. mem_pool->size = check_align_block(mem_pool->size);

  168. mem_pool->mem_block_count = mem_pool->size / MINUNITSIZE;

  169. // 鏈表化

  170. mem_pool->pfree_mem_chunk_pool = create_list(mem_pool->pfree_mem_chunk_pool, mem_pool->mem_map_pool_count);

  171. // 初始化 pfree_mem_chunk,雙向循環鏈表

  172. memory_chunk* tmp = front_pop(mem_pool->pfree_mem_chunk_pool);

  173. tmp->pre = tmp;

  174. tmp->next = tmp;

  175. tmp->pfree_mem_addr = NULL;

  176. mem_pool->mem_map_pool_count--;

  177.  
  178. // 初始化 pmem_map

  179. mem_pool->pmem_map[0].count = mem_pool->mem_block_count;

  180. mem_pool->pmem_map[0].pmem_chunk = tmp;

  181. mem_pool->pmem_map[mem_pool->mem_block_count-1].start = 0;

  182.  
  183. tmp->pfree_mem_addr = mem_pool->pmem_map;

  184. push_back(mem_pool->pfree_mem_chunk, tmp);

  185. mem_pool->free_mem_chunk_count = 1;

  186. mem_pool->mem_used_size = 0;

  187. return mem_pool;

  188. }

  189. /************************************************************************/

  190. /* 暫時沒用

  191. /************************************************************************/

  192. void ReleaseMemoryPool(PMEMORYPOOL* ppMem)

  193. {

  194. }

  195. /************************************************************************/

  196. /* 從內存池中分配指定大小的內存

  197. * pMem: 內存池 指針

  198. * sMemorySize: 要分配的內存大小

  199. * 成功時返回分配的內存起始地址,失敗返回NULL

  200. /************************************************************************/

  201. void* GetMemory(size_t sMemorySize, PMEMORYPOOL pMem)

  202. {

  203. sMemorySize = check_align_size(sMemorySize);

  204. size_t index = 0;

  205. memory_chunk* tmp = pMem->pfree_mem_chunk;

  206. for (index = 0; index < pMem->free_mem_chunk_count; index++)

  207. {

  208. if (tmp->pfree_mem_addr->count * MINUNITSIZE >= sMemorySize)

  209. {

  210. break;

  211. }

  212.  
  213. tmp = tmp->next;

  214. }

  215.  
  216. if (index == pMem->free_mem_chunk_count)

  217. {

  218. return NULL;

  219. }

  220. pMem->mem_used_size += sMemorySize;

  221. if (tmp->pfree_mem_addr->count * MINUNITSIZE == sMemorySize)

  222. {

  223. // 當要分配的內存大小與當前chunk中的內存大小相同時,從pfree_mem_chunk鏈表中刪除此chunk

  224. size_t current_index = (tmp->pfree_mem_addr - pMem->pmem_map);

  225. delete_chunk(pMem->pfree_mem_chunk, tmp);

  226. tmp->pfree_mem_addr->pmem_chunk = NULL;

  227.  
  228. push_front(pMem->pfree_mem_chunk_pool, tmp);

  229. pMem->free_mem_chunk_count--;

  230. pMem->mem_map_pool_count++;

  231.  
  232. return index2addr(pMem, current_index);

  233. }

  234. else

  235. {

  236. // 當要分配的內存小於當前chunk中的內存時,更改pfree_mem_chunk中相應chunk的pfree_mem_addr

  237.  
  238. // 複製當前mem_map_unit

  239. memory_block copy;

  240. copy.count = tmp->pfree_mem_addr->count;

  241. copy.pmem_chunk = tmp;

  242. // 記錄該block的起始和結束索引

  243. memory_block* current_block = tmp->pfree_mem_addr;

  244. current_block->count = sMemorySize / MINUNITSIZE;

  245. size_t current_index = (current_block - pMem->pmem_map);

  246. pMem->pmem_map[current_index+current_block->count-1].start = current_index;

  247. current_block->pmem_chunk = NULL; // NULL表示當前內存塊已被分配

  248. // 當前block被一分爲二,更新第二個block中的內容

  249. pMem->pmem_map[current_index+current_block->count].count = copy.count - current_block->count;

  250. pMem->pmem_map[current_index+current_block->count].pmem_chunk = copy.pmem_chunk;

  251. // 更新原來的pfree_mem_addr

  252. tmp->pfree_mem_addr = &(pMem->pmem_map[current_index+current_block->count]);

  253.  
  254. size_t end_index = current_index + copy.count - 1;

  255. pMem->pmem_map[end_index].start = current_index + current_block->count;

  256. return index2addr(pMem, current_index);

  257. }

  258. }

  259. /************************************************************************/

  260. /* 從內存池中釋放申請到的內存

  261. * pMem:內存池指針

  262. * ptrMemoryBlock:申請到的內存起始地址

  263. /************************************************************************/

  264. void FreeMemory(void *ptrMemoryBlock, PMEMORYPOOL pMem)

  265. {

  266. size_t current_index = addr2index(pMem, ptrMemoryBlock);

  267. size_t size = pMem->pmem_map[current_index].count * MINUNITSIZE;

  268. // 判斷與當前釋放的內存塊相鄰的內存塊是否可以與當前釋放的內存塊合併

  269. memory_block* pre_block = NULL;

  270. memory_block* next_block = NULL;

  271. memory_block* current_block = &(pMem->pmem_map[current_index]);

  272. // 第一個

  273. if (current_index == 0)

  274. {

  275. if (current_block->count < pMem->mem_block_count)

  276. {

  277. next_block = &(pMem->pmem_map[current_index+current_block->count]);

  278. // 如果後一個內存塊是空閒的,合併

  279. if (next_block->pmem_chunk != NULL)

  280. {

  281. next_block->pmem_chunk->pfree_mem_addr = current_block;

  282. pMem->pmem_map[current_index+current_block->count+next_block->count-1].start = current_index;

  283. current_block->count += next_block->count;

  284. current_block->pmem_chunk = next_block->pmem_chunk;

  285. next_block->pmem_chunk = NULL;

  286. }

  287. // 如果後一塊內存不是空閒的,在pfree_mem_chunk中增加一個chunk

  288. else

  289. {

  290. memory_chunk* new_chunk = front_pop(pMem->pfree_mem_chunk_pool);

  291. new_chunk->pfree_mem_addr = current_block;

  292. current_block->pmem_chunk = new_chunk;

  293. push_back(pMem->pfree_mem_chunk, new_chunk);

  294. pMem->mem_map_pool_count--;

  295. pMem->free_mem_chunk_count++;

  296. }

  297. }

  298. else

  299. {

  300. memory_chunk* new_chunk = front_pop(pMem->pfree_mem_chunk_pool);

  301. new_chunk->pfree_mem_addr = current_block;

  302. current_block->pmem_chunk = new_chunk;

  303. push_back(pMem->pfree_mem_chunk, new_chunk);

  304. pMem->mem_map_pool_count--;

  305. pMem->free_mem_chunk_count++;

  306. }

  307. }

  308.  
  309. // 最後一個

  310. else if (current_index == pMem->mem_block_count-1)

  311. {

  312. if (current_block->count < pMem->mem_block_count)

  313. {

  314. pre_block = &(pMem->pmem_map[current_index-1]);

  315. size_t index = pre_block->count;

  316. pre_block = &(pMem->pmem_map[index]);

  317.  
  318. // 如果前一個內存塊是空閒的,合併

  319. if (pre_block->pmem_chunk != NULL)

  320. {

  321. pMem->pmem_map[current_index+current_block->count-1].start = current_index - pre_block->count;

  322. pre_block->count += current_block->count;

  323. current_block->pmem_chunk = NULL;

  324. }

  325. // 如果前一塊內存不是空閒的,在pfree_mem_chunk中增加一個chunk

  326. else

  327. {

  328. memory_chunk* new_chunk = front_pop(pMem->pfree_mem_chunk_pool);

  329. new_chunk->pfree_mem_addr = current_block;

  330. current_block->pmem_chunk = new_chunk;

  331. push_back(pMem->pfree_mem_chunk, new_chunk);

  332. pMem->mem_map_pool_count--;

  333. pMem->free_mem_chunk_count++;

  334. }

  335. }

  336. else

  337. {

  338. memory_chunk* new_chunk = front_pop(pMem->pfree_mem_chunk_pool);

  339. new_chunk->pfree_mem_addr = current_block;

  340. current_block->pmem_chunk = new_chunk;

  341. push_back(pMem->pfree_mem_chunk, new_chunk);

  342. pMem->mem_map_pool_count--;

  343. pMem->free_mem_chunk_count++;

  344. }

  345. }

  346. else

  347. {

  348. next_block = &(pMem->pmem_map[current_index+current_block->count]);

  349. pre_block = &(pMem->pmem_map[current_index-1]);

  350. size_t index = pre_block->start;

  351. pre_block = &(pMem->pmem_map[index]);

  352. bool is_back_merge = false;

  353. if (next_block->pmem_chunk == NULL && pre_block->pmem_chunk == NULL)

  354. {

  355. memory_chunk* new_chunk = front_pop(pMem->pfree_mem_chunk_pool);

  356. new_chunk->pfree_mem_addr = current_block;

  357. current_block->pmem_chunk = new_chunk;

  358. push_back(pMem->pfree_mem_chunk, new_chunk);

  359. pMem->mem_map_pool_count--;

  360. pMem->free_mem_chunk_count++;

  361. }

  362. // 後一個內存塊

  363. if (next_block->pmem_chunk != NULL)

  364. {

  365. next_block->pmem_chunk->pfree_mem_addr = current_block;

  366. pMem->pmem_map[current_index+current_block->count+next_block->count-1].start = current_index;

  367. current_block->count += next_block->count;

  368. current_block->pmem_chunk = next_block->pmem_chunk;

  369. next_block->pmem_chunk = NULL;

  370. is_back_merge = true;

  371. }

  372. // 前一個內存塊

  373. if (pre_block->pmem_chunk != NULL)

  374. {

  375. pMem->pmem_map[current_index+current_block->count-1].start = current_index - pre_block->count;

  376. pre_block->count += current_block->count;

  377. if (is_back_merge)

  378. {

  379. delete_chunk(pMem->pfree_mem_chunk, current_block->pmem_chunk);

  380. push_front(pMem->pfree_mem_chunk_pool, current_block->pmem_chunk);

  381. pMem->free_mem_chunk_count--;

  382. pMem->mem_map_pool_count++;

  383. }

  384. current_block->pmem_chunk = NULL;

  385. }

  386. }

  387. pMem->mem_used_size -= size;

  388. }

MemoryPoolTest.cpp


 
  1. // memory pool test.cpp : Defines the entry point for the console application.

  2. #include <tchar.h>

  3. #include "MemoryPool.h"

  4. #include <iostream>

  5. #include <windows.h>

  6. #include <vector>

  7. #include <time.h>

  8. #include <math.h>

  9. #include <fstream>

  10. using namespace std;

  11. int break_time = 0;

  12. // 檢測內存池相關參數

  13. void check_mem_pool(int& max_chunk_size, int& free_chunk_count, int& min_chunk_size, int& total_free_mem, MEMORYPOOL* mem_pool)

  14. {

  15. memory_chunk* head = mem_pool->pfree_mem_chunk;

  16. memory_chunk* tmp = head;

  17. free_chunk_count = 0;

  18. total_free_mem = 0;

  19. max_chunk_size = 0;

  20. min_chunk_size = 500*1024*1024;

  21. if (head == NULL)

  22. {

  23. min_chunk_size = 0;

  24. return;

  25. }

  26. while (tmp->next != head)

  27. {

  28. free_chunk_count++;

  29. total_free_mem += tmp->pfree_mem_addr->count * MINUNITSIZE;

  30. if (tmp->pfree_mem_addr->count * MINUNITSIZE > max_chunk_size )

  31. {

  32. max_chunk_size = tmp->pfree_mem_addr->count * MINUNITSIZE;

  33. }

  34. if (tmp->pfree_mem_addr->count * MINUNITSIZE < min_chunk_size)

  35. {

  36. min_chunk_size = tmp->pfree_mem_addr->count * MINUNITSIZE;

  37. }

  38. tmp = tmp->next;

  39. }

  40. free_chunk_count++;

  41. total_free_mem += tmp->pfree_mem_addr->count * MINUNITSIZE;

  42. if (tmp->pfree_mem_addr->count * MINUNITSIZE > max_chunk_size )

  43. {

  44. max_chunk_size = tmp->pfree_mem_addr->count * MINUNITSIZE;

  45. }

  46. if (tmp->pfree_mem_addr->count * MINUNITSIZE < min_chunk_size)

  47. {

  48. min_chunk_size = tmp->pfree_mem_addr->count * MINUNITSIZE;

  49. }

  50. }

  51. // 申請後緊接着釋放

  52. double test_mem_pool_perf_1(PMEMORYPOOL mem_pool, int iter, int* sizes)

  53. {

  54. cout << "*********************test_mem_pool_perf_1*********************" << endl;

  55. LARGE_INTEGER litmp;

  56. LONGLONG QPart1, QPart2;

  57. double t;

  58. double dfMinus, dfFreq;

  59. QueryPerformanceFrequency(&litmp);

  60. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  61. QueryPerformanceCounter(&litmp);

  62. QPart1 = litmp.QuadPart;// 獲得初始值

  63. for (int i = 0; i < iter; i++)

  64. {

  65. void *p = GetMemory(sizes[i], mem_pool);

  66. if (p == NULL)

  67. {

  68. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << sizes[i] << " Byte" << endl;

  69. cout << "total memory is: " << mem_pool->size << " Byte" << endl;

  70. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl;

  71. cout << "memory left is: " << mem_pool->size - mem_pool->mem_used_size << endl << endl;

  72. int max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem;

  73. check_mem_pool(max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem, mem_pool);

  74. cout << "check memory pool result:" << endl;

  75. cout << "free_chunk_count: " << free_chunk_count << endl

  76. << "total_free_mem: " << total_free_mem << endl

  77. << "max_chunk_size: " << max_chunk_size << endl

  78. << "min_chunk_size: " << min_chunk_size << endl;

  79. break;

  80. }

  81. FreeMemory(p, mem_pool);

  82. }

  83. QueryPerformanceCounter(&litmp);

  84. QPart2 = litmp.QuadPart;//獲得中止值

  85. dfMinus = (double)(QPart2-QPart1);

  86. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  87. cout << "test_mem_pool_perf_1: iter = " << iter << endl;

  88. cout << "time: " << t << endl;

  89. cout << "*********************test_mem_pool_perf_1*********************" << endl << endl << endl;

  90. return t;

  91. }

  92. double test_std_perf_1(int iter, int* sizes)

  93. {

  94. cout << "*********************test_std_perf_1*********************" << endl;

  95. LARGE_INTEGER litmp;

  96. LONGLONG QPart1, QPart2;

  97. double t;

  98. double dfMinus, dfFreq;

  99. QueryPerformanceFrequency(&litmp);

  100. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  101. QueryPerformanceCounter(&litmp);

  102. QPart1 = litmp.QuadPart;// 獲得初始值

  103. for (int i = 0; i < iter; i++)

  104. {

  105. void *p = malloc(sizes[i]);

  106. if (p == NULL)

  107. {

  108. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << sizes[i] << " Byte" << endl;

  109. break;

  110. }

  111. free(p);

  112. }

  113. QueryPerformanceCounter(&litmp);

  114. QPart2 = litmp.QuadPart;//獲得中止值

  115. dfMinus = (double)(QPart2-QPart1);

  116. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  117. cout << "test_std_perf_1: iter = " << iter << endl;

  118. cout << "time: " << t << endl;

  119. cout << "*********************test_std_perf_1*********************" << endl << endl << endl;

  120. return t;

  121. }

  122. // 連續申請iter/2次,然後釋放所有申請內存;再重複一次

  123. double test_mem_pool_perf_2(PMEMORYPOOL mem_pool, int iter, int size)

  124. {

  125. cout << "*********************test_mem_pool_perf_2*********************" << endl;

  126. LARGE_INTEGER litmp;

  127. LONGLONG QPart1, QPart2;

  128. double t;

  129. double dfMinus, dfFreq;

  130. QueryPerformanceFrequency(&litmp);

  131. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  132. QueryPerformanceCounter(&litmp);

  133. QPart1 = litmp.QuadPart;// 獲得初始值

  134. void **p = new void*[iter];

  135. if (p == NULL)

  136. {

  137. cout << "new faild" << endl;

  138. return -1;

  139. }

  140. int count = 0;

  141. for (int i = 0; i < iter/2; i++)

  142. {

  143. p[i] = GetMemory(size, mem_pool);

  144. if (p[i] == NULL)

  145. {

  146. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  147. cout << "total memory is: " << mem_pool->size << " Byte" << endl;

  148. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl;

  149. cout << "memory left is: " << mem_pool->size - mem_pool->mem_used_size << endl << endl;

  150. int max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem;

  151. check_mem_pool(max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem, mem_pool);

  152. cout << "check memory pool result:" << endl;

  153. cout << "free_chunk_count: " << free_chunk_count << endl

  154. << "total_free_mem: " << total_free_mem << endl

  155. << "max_chunk_size: " << max_chunk_size << endl

  156. << "min_chunk_size: " << min_chunk_size << endl;

  157. break;

  158. }

  159. count++;

  160. }

  161. for (int i = 0; i < count; i++)

  162. {

  163. FreeMemory(p[i], mem_pool);

  164. }

  165. count = 0;

  166. for (int i = 0; i < iter/2; i++)

  167. {

  168. p[i] = GetMemory(size, mem_pool);

  169. if (p[i] == NULL)

  170. {

  171. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  172. cout << "total memory is: " << mem_pool->size << " Byte" << endl;

  173. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl;

  174. cout << "memory left is: " << mem_pool->size - mem_pool->mem_used_size << endl << endl;

  175.  
  176. int max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem;

  177. check_mem_pool(max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem, mem_pool);

  178. cout << "check memory pool result:" << endl;

  179. cout << "free_chunk_count: " << free_chunk_count << endl

  180. << "total_free_mem: " << total_free_mem << endl

  181. << "max_chunk_size: " << max_chunk_size << endl

  182. << "min_chunk_size: " << min_chunk_size << endl;

  183. break;

  184. }

  185. count++;

  186. }

  187. for (int i = 0; i < count; i++)

  188. {

  189. if (p[i] == NULL)

  190. {

  191. cout << i << endl;

  192. break;

  193. }

  194. FreeMemory(p[i], mem_pool);

  195. }

  196. QueryPerformanceCounter(&litmp);

  197. QPart2 = litmp.QuadPart;//獲得中止值

  198. dfMinus = (double)(QPart2-QPart1);

  199. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  200. cout << "test_mem_pool_perf_2: iter = " << iter << endl;

  201. cout << "time: " << t << endl;

  202. delete []p;

  203. cout << "*********************test_mem_pool_perf_2*********************" << endl << endl << endl;

  204. return t;

  205. }

  206. // 連續申請inner_iter次,釋放;重複iter/inner_iter次

  207. double test_mem_pool_perf_3(PMEMORYPOOL mem_pool, int iter, int size)

  208. {

  209. cout << "*********************test_mem_pool_perf_3*********************" << endl;

  210. int inner_iter = 10;

  211. void **p = new void*[inner_iter];

  212. if (p == NULL)

  213. {

  214. cout << "new faild" << endl;

  215. return -1;

  216. }

  217. LARGE_INTEGER litmp;

  218. LONGLONG QPart1, QPart2, start, finish;

  219. double t;

  220. double dfMinus, dfFreq;

  221. QueryPerformanceFrequency(&litmp);

  222. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  223. QueryPerformanceCounter(&litmp);

  224. QPart1 = litmp.QuadPart;// 獲得初始值

  225. for (int k = 0; k < iter / inner_iter; k++)

  226. {

  227. int j = 0;

  228. for (j = 0; j < inner_iter; j++)

  229. {

  230. p[j] = GetMemory(size, mem_pool);

  231. if (p[j] == NULL)

  232. {

  233. cout << "break @ iterator = " << j << " / " << iter << ", need memory " << size << " Byte" << endl;

  234. cout << "total memory is: " << mem_pool->size << " Byte" << endl;

  235. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl;

  236. cout << "memory left is: " << mem_pool->size - mem_pool->mem_used_size << endl << endl;

  237. int max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem;

  238. check_mem_pool(max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem, mem_pool);

  239. cout << "check memory pool result:" << endl;

  240. cout << "free_chunk_count: " << free_chunk_count << endl

  241. << "total_free_mem: " << total_free_mem << endl

  242. << "max_chunk_size: " << max_chunk_size << endl

  243. << "min_chunk_size: " << min_chunk_size << endl;

  244. break;

  245. }

  246. }

  247. for (int i = 0; i < j; i++)

  248. {

  249. FreeMemory(p[i], mem_pool);

  250. }

  251. }

  252. QueryPerformanceCounter(&litmp);

  253. QPart2 = litmp.QuadPart;//獲得中止值

  254. dfMinus = (double)(QPart2-QPart1);

  255. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  256. cout << "test_mem_pool_perf_3: iter = " << iter << endl;

  257. cout << "time: " << t << endl;

  258. cout << "*********************test_mem_pool_perf_3*********************" << endl << endl << endl;

  259. return t;

  260. }

  261. // 隨機內存大小,隨機釋放操作

  262. double test_mem_pool_perf_rand(PMEMORYPOOL mem_pool, int iter, int* sizes, int* instruction)

  263. {

  264. cout << "-----------------------test_mem_pool_perf_rand----------------------- "<< endl;

  265. void** p = new void*[iter];

  266. if (p == NULL)

  267. {

  268. cout << "new failed" << endl;

  269. return -1;

  270. }

  271. LARGE_INTEGER litmp, gftime;

  272. LONGLONG QPart1, QPart2, start, finish;

  273. double t, GetMemory_time, FreeMemory_time;

  274. double dfMinus, dfFreq;

  275. QueryPerformanceFrequency(&litmp);

  276. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  277. QueryPerformanceCounter(&litmp);

  278. QPart1 = litmp.QuadPart;// 獲得初始值

  279. int index = 0;

  280. int size;

  281. int free_tmp = 0;

  282. double seach_time;

  283. for (int i = 0; i < iter; i++)

  284. {

  285. size = sizes[i];

  286. p[index++] = GetMemory(size, mem_pool);

  287. if (p[index-1] == NULL)

  288. {

  289. break_time++;

  290. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  291. cout << "total memory is: " << mem_pool->size << " Byte" << endl;

  292. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl;

  293. cout << "memory left is: " << mem_pool->size - mem_pool->mem_used_size << endl << endl;

  294. int max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem;

  295. check_mem_pool(max_chunk_size, free_chunk_count, min_chunk_size, total_free_mem, mem_pool);

  296. cout << "check memory pool result:" << endl;

  297. cout << "free_chunk_count: " << free_chunk_count << endl

  298. << "total_free_mem: " << total_free_mem << endl

  299. << "max_chunk_size: " << max_chunk_size << endl

  300. << "min_chunk_size: " << min_chunk_size << endl;

  301. break;

  302. }

  303.  
  304. if (instruction[i] == 1)

  305. {

  306. FreeMemory(p[--index], mem_pool);

  307. }

  308. }

  309. QueryPerformanceCounter(&litmp);

  310. QPart2 = litmp.QuadPart;//獲得中止值

  311. dfMinus = (double)(QPart2-QPart1);

  312. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  313. cout << "test_mem_pool_perf_rand: iter = " << iter << endl;

  314. cout << "time: " << t << endl << endl;

  315. delete []p;

  316. return t;

  317. }

  318. double test_std_perf(int iter, int* sizes, int* instruction)

  319. {

  320. cout << "test_std_perf" << endl;

  321. void** p =new void*[iter];

  322. if (p == NULL)

  323. {

  324. cout << "new failed" << endl;

  325. return -1;

  326. }

  327.  
  328. LARGE_INTEGER litmp;

  329. LONGLONG QPart1, QPart2;

  330. double t;

  331. double dfMinus, dfFreq;

  332. QueryPerformanceFrequency(&litmp);

  333. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  334. QueryPerformanceCounter(&litmp);

  335. QPart1 = litmp.QuadPart;// 獲得初始值

  336. // cout << "test start" << endl;

  337. int index = 0;

  338. int size;

  339. for (int i = 0; i < iter; i++)

  340. {

  341. size = sizes[i];

  342. p[index++] = malloc(size);

  343. if (p[index-1] == NULL)

  344. {

  345. cout << i << endl;

  346. break;

  347. }

  348. if (instruction[i] == 1)

  349. {

  350. free(p[--index]);

  351. }

  352. }

  353. QueryPerformanceCounter(&litmp);

  354. QPart2 = litmp.QuadPart;//獲得中止值

  355. dfMinus = (double)(QPart2-QPart1);

  356. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  357. cout << "test_std_perf: iter = " << iter << endl;

  358. cout << "time: " << t << endl << endl;

  359. for (int k = 0; k < index; k++)

  360. {

  361. free(p[k]);

  362. }

  363. return t;

  364. }

  365. double test_std_perf_fix_size(int iter, int size)

  366. {

  367. cout << "******************* test_std_perf_fix_size *******************" << endl;

  368. LARGE_INTEGER litmp;

  369. LONGLONG QPart1, QPart2;

  370. double t;

  371. double dfMinus, dfFreq;

  372. QueryPerformanceFrequency(&litmp);

  373. dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率

  374. QueryPerformanceCounter(&litmp);

  375. QPart1 = litmp.QuadPart;// 獲得初始值

  376. int index = 0;

  377.  
  378. for (int i = 0; i < iter; i++)

  379. {

  380. void *p = malloc(size);

  381. if (p == NULL)

  382. {

  383. cout << i << endl;

  384. break;

  385. }

  386. free(p);

  387. }

  388. QueryPerformanceCounter(&litmp);

  389. QPart2 = litmp.QuadPart;//獲得中止值

  390. dfMinus = (double)(QPart2-QPart1);

  391. t = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒

  392. cout << "test_std_perf: iter = " << iter << endl;

  393. cout << "time: " << t << endl;

  394. cout << "******************* test_std_perf_fix_size *******************" << endl << endl << endl;

  395. return t;

  396. }

  397. void test_correct_1(PMEMORYPOOL mem_pool, int iter, int size)

  398. {

  399. vector<void*>vec;

  400. vector<void*>::iterator vec_iter;

  401. int i = 0;

  402. cout << "**************************** Get Memory Test Start ****************************"<< endl << endl;

  403. for (i = 0; i < iter; i++)

  404. {

  405. void *p = GetMemory(size, mem_pool);

  406. if (p == NULL)

  407. {

  408. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  409. cout << "memory left is: " << mem_pool->size << " Byte" << endl;

  410. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl << endl;

  411. break;

  412. }

  413. vec.push_back(p);

  414. }

  415. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  416. cout << "memory left is: " << mem_pool->size << " Byte" << endl;

  417. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl << endl;

  418. cout << "verify memory size" << endl;

  419. memory_chunk* tmp = mem_pool->pfree_mem_chunk;

  420. int free_size = 0;

  421. for (int k = 0; k < mem_pool->free_mem_chunk_count; k++)

  422. {

  423. free_size += tmp->pfree_mem_addr->count * MINUNITSIZE;

  424. tmp = tmp->next;

  425. }

  426. cout << "memory free size is " << free_size << " Byte" << endl;

  427. cout << "memory used size is " << mem_pool->mem_used_size << " Byte" << endl;

  428. cout << "*************************** Get Memory Test Finish ***************************"<< endl << endl;

  429. cout << "*************************** Free Memory Test Start ***************************"<< endl << endl;

  430. int index = 0;

  431. for (vec_iter = vec.begin(); vec_iter != vec.end(); vec_iter++)

  432. {

  433. index++;

  434. FreeMemory(*vec_iter, mem_pool);

  435. }

  436. cout << "memory left is: " << mem_pool->size << " Byte" << endl;

  437. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl << endl;

  438. cout << "*************************** Free Memory Test Finish ***************************"<< endl << endl;

  439. cout << "********************* Get Memory Test (after Free) Start *********************"<< endl << endl;

  440. for (i = 0; i < iter; i++)

  441. {

  442. void *p = GetMemory(size, mem_pool);

  443. if (p == NULL)

  444. {

  445. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  446. cout << "memory left is: " << mem_pool->size << " Byte" << endl;

  447. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl << endl;

  448. int max_size = 0;

  449. memory_chunk* tmp = mem_pool->pfree_mem_chunk;

  450. for (int k = 0; k < mem_pool->free_mem_chunk_count; k++)

  451. {

  452. if (tmp->pfree_mem_addr->count * MINUNITSIZE > max_size)

  453. {

  454. max_size = tmp->pfree_mem_addr->count * MINUNITSIZE > max_size;

  455. }

  456. }

  457. cout << "max chunk size is: " << max_size << " Byte" << endl;

  458. break;

  459. }

  460. vec.push_back(p);

  461. }

  462. cout << "break @ iterator = " << i << " / " << iter << ", need memory " << size << " Byte" << endl;

  463. cout << "memory left is: " << mem_pool->size << " Byte" << endl;

  464. cout << "memory used is: " << mem_pool->mem_used_size << " Byte" << endl << endl;

  465. cout << "verify memory size" << endl;

  466. tmp = mem_pool->pfree_mem_chunk;

  467. free_size = 0;

  468. for (int k = 0; k < mem_pool->free_mem_chunk_count; k++)

  469. {

  470. free_size += tmp->pfree_mem_addr->count * MINUNITSIZE;

  471. tmp = tmp->next;

  472. }

  473. cout << "memory free size is " << free_size << " Byte" << endl;

  474. cout << "memory used size is " << mem_pool->mem_used_size << " Byte" << endl;

  475. cout << "********************* Get Memory Test (after Free) Finish *********************"<< endl << endl;

  476. }

  477. /************************************************************************/

  478. /* 內存池性能測試代碼

  479. * 固定大小

  480. /************************************************************************/

  481. /*

  482. void test_mem_pool_fix_size(PMEMORYPOOL mem_pool)

  483. {

  484. int iter = 200000;

  485. int size = 512;

  486. double t1 = test_std_perf_fix_size(iter, size);

  487. double t2 = test_mem_pool_perf_1(mem_pool, iter, size);

  488. double t3 = test_mem_pool_perf_2(mem_pool, iter, size);

  489. double t4 = test_mem_pool_perf_3(mem_pool, iter, size);

  490. cout << endl << endl

  491. << "test count: " << iter << ", test size: " << size << endl

  492. << "test result (system time / mem_pool time) : " << endl;

  493. cout << "test_mem_pool_perf_1: " << t1 / t2 << endl

  494. << "test_mem_pool_perf_2: " << t1 / t3 << endl

  495. << "test_mem_pool_perf_3: " << t1 / t4 << endl;

  496. }

  497. */

  498. /************************************************************************/

  499. /* 內存池性能測試代碼

  500.  
  501. * 隨機大小,隨機釋放操作

  502. /************************************************************************/

  503. void rand_test()

  504. {

  505. size_t sBufSize = 500* 1024*1024;

  506. void*pBuf = malloc(sBufSize);

  507. if (pBuf == NULL)

  508. {

  509. cout << "malloc failed" << endl;

  510. return;

  511. }

  512. PMEMORYPOOL mem_pool = CreateMemoryPool(pBuf, sBufSize);

  513. ofstream out("rand_test.txt");

  514. int iter = 2000;

  515. int* instruction = new int[iter];

  516. int* sizes = new int[iter];

  517. if (instruction == NULL || sizes == NULL)

  518. {

  519. cout << "new memory failed" << endl;

  520. return;

  521. }

  522. srand(time(NULL));

  523. cout << "generate rand number" << endl;

  524. // instruction 中元素爲1時表示在GetMemory後執行FreeMemory,0表示不執行FreeMemory

  525. // sizes中是每次分配內存的大小,範圍從64B~1024B

  526. for (int i = 0; i < iter; i++)

  527. {

  528. instruction[i] = rand() % 2;

  529. sizes[i] = (rand() % 16 + 1) * 64;

  530. }

  531. int test_count = 200;

  532. double t1, t2;

  533. double* ratio = new double[test_count];

  534. int count = 0;

  535. for (int k = 0; k < test_count; k++)

  536. {

  537. if (break_time != 0)

  538. {

  539. cout << "break @ " << k << " / " << test_count << endl;

  540. break;

  541. }

  542. count++;

  543. cout << "******************************************test " << k+1 << " *************************************************" << endl;

  544. t1 = test_std_perf(iter, sizes, instruction);

  545. t2 = test_mem_pool_perf_rand(mem_pool, iter, sizes, instruction);

  546. cout << "total memory: " << mem_pool->size << ", memory used: " << mem_pool->mem_used_size

  547. << ", memory left: " << mem_pool->size - mem_pool->mem_used_size << endl;

  548. ratio[k] = t1 / t2;

  549.  
  550. }

  551. if(break_time == 0)

  552. break_time = test_count;

  553. break_time = count - 1;

  554. cout << "*************************** ratio (system time / mem_pool time) ***************************" << endl;

  555. for (int k = 0; k < break_time; k++)

  556. {

  557. out << ratio[k] << ",";

  558. if (k % 10 == 0 && k != 0)

  559. {

  560. cout << endl;

  561. }

  562. cout << ratio[k] << " ";

  563. }

  564. cout << endl;

  565. delete []ratio;

  566. delete []instruction;

  567. delete []sizes;

  568. free(pBuf);

  569. }

  570. // 申請緊接着釋放

  571. void rand_test_2()

  572. {

  573. size_t sBufSize = 500* 1024*1024;

  574. void*pBuf = malloc(sBufSize);

  575. if (pBuf == NULL)

  576. {

  577. cout << "malloc failed" << endl;

  578. return;

  579. }

  580. PMEMORYPOOL mem_pool = CreateMemoryPool(pBuf, sBufSize);

  581. int iter = 2000;

  582. int test_count = 511;

  583. int* sizes = new int[iter];

  584. double* ratio = new double[test_count];

  585. if (sizes == NULL || ratio == NULL)

  586. {

  587. cout << "new memory failed" << endl;

  588. return;

  589. }

  590. srand(time(NULL));

  591. cout << "generate rand number" << endl;

  592. ofstream out("rand_test_2.txt");

  593. for (int k = 0; k < test_count; k++)

  594. {

  595. for (int i = 0; i < iter; i++)

  596. {

  597. sizes[i] = (rand() % 16 + 1) * 64 + 1024 * k;

  598. }

  599. double mem_pool_t = test_mem_pool_perf_1(mem_pool, iter, sizes);

  600. double std_t = test_std_perf_1(iter, sizes);

  601.  
  602. ratio[k] = std_t / mem_pool_t;

  603. }

  604. cout << "*************************** ratio (system time / mem_pool time) ***************************" << endl;

  605. for (int k = 0; k < test_count; k++)

  606. {

  607. out << ratio[k] << ",";

  608. if (k % 10 == 0 && k != 0)

  609. {

  610. cout << endl;

  611. }

  612. cout << ratio[k] << " ";

  613. }

  614. cout << endl;

  615.  
  616. delete []sizes;

  617. delete ratio;

  618. free(pBuf);

  619. }

  620. int _tmain(int argc, _TCHAR* argv[])

  621. {

  622. rand_test();

  623. // rand_test_2();

  624.  
  625. return 0;

  626. }

轉自https://blog.csdn.net/shawngucas/article/details/6574863

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章