You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

allocator.cpp 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "allocator.h"
  15. #include <stdio.h>
  16. namespace ncnn {
  17. PoolAllocator::PoolAllocator()
  18. {
  19. size_compare_ratio = 192;// 0.75f * 256
  20. }
  21. PoolAllocator::~PoolAllocator()
  22. {
  23. clear();
  24. if (!payouts.empty())
  25. {
  26. fprintf(stderr, "FATAL ERROR! pool allocator destroyed too early\n");
  27. std::list< std::pair<size_t, void*> >::iterator it = payouts.begin();
  28. for (; it != payouts.end(); it++)
  29. {
  30. void* ptr = it->second;
  31. fprintf(stderr, "%p still in use\n", ptr);
  32. }
  33. }
  34. }
  35. void PoolAllocator::clear()
  36. {
  37. budgets_lock.lock();
  38. std::list< std::pair<size_t, void*> >::iterator it = budgets.begin();
  39. for (; it != budgets.end(); it++)
  40. {
  41. void* ptr = it->second;
  42. ncnn::fastFree(ptr);
  43. }
  44. budgets.clear();
  45. budgets_lock.unlock();
  46. }
  47. void PoolAllocator::set_size_compare_ratio(float scr)
  48. {
  49. if (scr < 0.f || scr > 1.f)
  50. {
  51. fprintf(stderr, "invalid size compare ratio %f\n", scr);
  52. return;
  53. }
  54. size_compare_ratio = (unsigned int)(scr * 256);
  55. }
  56. void* PoolAllocator::fastMalloc(size_t size)
  57. {
  58. budgets_lock.lock();
  59. // find free budget
  60. std::list< std::pair<size_t, void*> >::iterator it = budgets.begin();
  61. for (; it != budgets.end(); it++)
  62. {
  63. size_t bs = it->first;
  64. // size_compare_ratio ~ 100%
  65. if (bs >= size && ((bs * size_compare_ratio) >> 8) <= size)
  66. {
  67. void* ptr = it->second;
  68. budgets.erase(it);
  69. budgets_lock.unlock();
  70. payouts_lock.lock();
  71. payouts.push_back(std::make_pair(bs, ptr));
  72. payouts_lock.unlock();
  73. return ptr;
  74. }
  75. }
  76. budgets_lock.unlock();
  77. // new
  78. void* ptr = ncnn::fastMalloc(size);
  79. payouts_lock.lock();
  80. payouts.push_back(std::make_pair(size, ptr));
  81. payouts_lock.unlock();
  82. return ptr;
  83. }
  84. void PoolAllocator::fastFree(void* ptr)
  85. {
  86. payouts_lock.lock();
  87. // return to budgets
  88. std::list< std::pair<size_t, void*> >::iterator it = payouts.begin();
  89. for (; it != payouts.end(); it++)
  90. {
  91. if (it->second == ptr)
  92. {
  93. size_t size = it->first;
  94. payouts.erase(it);
  95. payouts_lock.unlock();
  96. budgets_lock.lock();
  97. budgets.push_back(std::make_pair(size, ptr));
  98. budgets_lock.unlock();
  99. return;
  100. }
  101. }
  102. payouts_lock.unlock();
  103. fprintf(stderr, "FATAL ERROR! pool allocator get wild %p\n", ptr);
  104. ncnn::fastFree(ptr);
  105. }
  106. UnlockedPoolAllocator::UnlockedPoolAllocator()
  107. {
  108. size_compare_ratio = 192;// 0.75f * 256
  109. }
  110. UnlockedPoolAllocator::~UnlockedPoolAllocator()
  111. {
  112. clear();
  113. if (!payouts.empty())
  114. {
  115. fprintf(stderr, "FATAL ERROR! unlocked pool allocator destroyed too early\n");
  116. std::list< std::pair<size_t, void*> >::iterator it = payouts.begin();
  117. for (; it != payouts.end(); it++)
  118. {
  119. void* ptr = it->second;
  120. fprintf(stderr, "%p still in use\n", ptr);
  121. }
  122. }
  123. }
  124. void UnlockedPoolAllocator::clear()
  125. {
  126. std::list< std::pair<size_t, void*> >::iterator it = budgets.begin();
  127. for (; it != budgets.end(); it++)
  128. {
  129. void* ptr = it->second;
  130. ncnn::fastFree(ptr);
  131. }
  132. budgets.clear();
  133. }
  134. void UnlockedPoolAllocator::set_size_compare_ratio(float scr)
  135. {
  136. if (scr < 0.f || scr > 1.f)
  137. {
  138. fprintf(stderr, "invalid size compare ratio %f\n", scr);
  139. return;
  140. }
  141. size_compare_ratio = (unsigned int)(scr * 256);
  142. }
  143. void* UnlockedPoolAllocator::fastMalloc(size_t size)
  144. {
  145. // find free budget
  146. std::list< std::pair<size_t, void*> >::iterator it = budgets.begin();
  147. for (; it != budgets.end(); it++)
  148. {
  149. size_t bs = it->first;
  150. // size_compare_ratio ~ 100%
  151. if (bs >= size && ((bs * size_compare_ratio) >> 8) <= size)
  152. {
  153. void* ptr = it->second;
  154. budgets.erase(it);
  155. payouts.push_back(std::make_pair(bs, ptr));
  156. return ptr;
  157. }
  158. }
  159. // new
  160. void* ptr = ncnn::fastMalloc(size);
  161. payouts.push_back(std::make_pair(size, ptr));
  162. return ptr;
  163. }
  164. void UnlockedPoolAllocator::fastFree(void* ptr)
  165. {
  166. // return to budgets
  167. std::list< std::pair<size_t, void*> >::iterator it = payouts.begin();
  168. for (; it != payouts.end(); it++)
  169. {
  170. if (it->second == ptr)
  171. {
  172. size_t size = it->first;
  173. payouts.erase(it);
  174. budgets.push_back(std::make_pair(size, ptr));
  175. return;
  176. }
  177. }
  178. fprintf(stderr, "FATAL ERROR! unlocked pool allocator get wild %p\n", ptr);
  179. ncnn::fastFree(ptr);
  180. }
  181. } // namespace ncnn