binning_memory_resource.hpp
前往此文件的文档。
1 /*
2  * 版权所有 (c) 2020-2025, 英伟达公司。
3  *
4  * 根据 Apache 许可证 2.0 版本(“许可证”)获得许可;
5  * 除非遵守许可证,否则您不得使用此文件。
6  * 您可以在以下网址获得许可证副本:
7  *
8  * https://apache.ac.cn/licenses/LICENSE-2.0
9  *
10  * 除非适用法律要求或书面同意,否则根据“按原样”基础分发的软件
11  * 不提供任何明示或默示的保证或条件。
12  * 请参阅许可证,了解特定语言的权限和限制。
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <rmm/aligned.hpp>
19 #include <rmm/detail/export.hpp>
22 #include <rmm/resource_ref.hpp>
23 
24 #include <cuda_runtime_api.h>
25 
26 #include <cassert>
27 #include <map>
28 #include <memory>
29 #include <optional>
30 #include <vector>
31 
32 namespace RMM_NAMESPACE {
33 namespace mr {
46 /// @brief 从与 bin 大小关联的上游资源分配内存。
47 template <typename Upstream>
57  public
58  /// @brief 构造一个新的 binning 内存资源对象。
59  /// @param upstream_resource 指向上游内存资源的 device_async_resource_ref。
60  explicit binning_memory_resource(device_async_resource_ref upstream_resource)
61  : upstream_mr_{upstream_resource}
62  {
72  }
73  /// @brief 构造一个新的 binning 内存资源对象。
74  /// @param upstream_resource 指向上游内存资源的指针。
75  explicit binning_memory_resource(Upstream* upstream_resource)
76  : upstream_mr_{to_device_async_resource_ref_checked(upstream_resource)}
89  {
90  }/// @brief 构造一个新的具有初始 bin 范围的 binning 内存资源对象。
91  /// @param upstream_resource 指向上游内存资源的 device_async_resource_ref。
92  /// @param min_size_exponent 最小 bin 大小,以 2 的幂为底。
93  /// @param max_size_exponent 最大 bin 大小,以 2 的幂为底。
95  int8_t min_size_exponent, // NOLINT(bugprone-easily-swappable-parameters)
96  int8_t max_size_exponent)
97  : upstream_mr_{upstream_resource}
98  {
113  for (auto i = min_size_exponent; i <= max_size_exponent; i++) {
114  add_bin(1 << i);
115  }
116  }/// @brief 构造一个新的具有初始 bin 范围的 binning 内存资源对象。
117  /// @param upstream_resource 指向上游内存资源的指针。
118  /// @param min_size_exponent 最小 bin 大小,以 2 的幂为底。
119  /// @param max_size_exponent 最大 bin 大小,以 2 的幂为底。
120  binning_memory_resource(Upstream* upstream_resource,
121  int8_t min_size_exponent, // NOLINT(bugprone-easily-swappable-parameters)
122  int8_t max_size_exponent)
127  : upstream_mr_{to_device_async_resource_ref_checked(upstream_resource)}
128  {
129  for (auto i = min_size_exponent; i <= max_size_exponent; i++) {
130  add_bin(1 << i);
131  }
132  }/// @brief 销毁 binning_memory_resource 并释放从上游资源分配的所有内存。
133  ~binning_memory_resource() override = default;
134 
141  binning_memory_resource& operator=(binning_memory_resource const&) = delete;
142  binning_memory_resource& operator=(binning_memory_resource&&) = delete;
143 
144  /// @brief 指向上游资源的 device_async_resource_ref
145  /// @return device_async_resource_ref 指向上游资源的 device_async_resource_ref
146  [[nodiscard]] device_async_resource_ref get_upstream_resource() const noexcept
147  {
148  return upstream_mr_;
149  }
150 
158  /// @brief 向此资源添加一个 bin 分配器。
159  /// @param allocation_size 此 bin 分配器分配的固定大小。
160  /// @param bin_resource 可选地提供要在此 bin 中使用的现有内存资源。如果提供,则不会在此 bin 中创建新的 fixed_size_memory_resource。
161  void add_bin(std::size_t allocation_size,
162  std::optional<device_async_resource_ref> bin_resource = std::nullopt)
163  {
164  allocation_size = align_up(allocation_size, CUDA_ALLOCATION_ALIGNMENT);
165 
166  if (bin_resource.has_value()) {
167  resource_bins_.insert({allocation_size, bin_resource.value()});
168  } else if (resource_bins_.count(allocation_size) == 0) { // 如果 bin 已存在则不执行任何操作
169  owned_bin_resources_.push_back(
170  std::make_unique<fixed_size_memory_resource<Upstream>>(upstream_mr_, allocation_size));
171  resource_bins_.insert({allocation_size, owned_bin_resources_.back().get()});
172  }
173  }
174 
175  private
181  /// @brief 查找能够容纳所请求分配大小的最小尺寸的 bin 资源。
182  /// @param bytes 要分配的大小。
183  /// @return device_async_resource_ref 能够容纳所请求分配大小的最小尺寸的 bin 资源。
184  device_async_resource_ref get_resource_ref(std::size_t bytes)
185  {
186  auto iter = resource_bins_.lower_bound(bytes);
196  return (iter != resource_bins_.cend()) ? iter->second : get_upstream_resource();
197  }/// @brief 使用适当的 bin 资源或上游资源分配大小为 \p bytes 的内存。
198  /// @param bytes 要分配的大小。
199  /// @param stream 要执行分配的 CUDA 流。
200  /// @return void* 指向分配内存的指针。
201  void* do_allocate(std::size_t bytes, cuda_stream_view stream) override
210  {
211  if (bytes <= 0) { return nullptr; }
212  return get_resource_ref(bytes).allocate_async(bytes, stream);
213  }/// @brief 使用正确的 bin 资源释放由 \p ptr 指向的、大小为 \p bytes 的内存。
214  /// @param ptr 指向要释放的内存的指针。
215  /// @param bytes 要释放的内存大小。
216  /// @param stream 要执行释放的 CUDA 流。
217  void do_deallocate(void* ptr, std::size_t bytes, cuda_stream_view stream) override
218  {
219  get_resource_ref(bytes).deallocate_async(ptr, bytes, stream);
220  }
221 
223  upstream_mr_; // 从中分配块的上游内存资源。
224 
225  std::vector<std::unique_ptr<fixed_size_memory_resource<Upstream>>> owned_bin_resources_;
226 
227  std::map<std::size_t, device_async_resource_ref> resource_bins_;
220  }
228 };
229  // 组结束
231 } // namespace mr
232 } // namespace RMM_NAMESPACE
aligned.hpp
rmm::cuda_stream_view
220  }
CUDA 流的强类型非拥有包装器,带默认构造函数。
229  // 组结束
定义: cuda_stream_view.hpp:39
220  }
rmm::mr::binning_memory_resource
从与 bin 大小关联的上游资源分配内存。
rmm::mr::binning_memory_resource::binning_memory_resource
binning_memory_resource(Upstream *upstream_resource)
构造一个新的 binning 内存资源对象。
rmm::mr::binning_memory_resource::get_upstream_resource
device_async_resource_ref get_upstream_resource() const noexcept
定义: binning_memory_resource.hpp:138
binning_memory_resource(device_async_resource_ref upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
~binning_memory_resource() override=default
销毁 binning_memory_resource 并释放从上游资源分配的所有内存。
binning_memory_resource(Upstream *upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
binning_memory_resource(device_async_resource_ref upstream_resource)
定义: binning_memory_resource.hpp:57
rmm::mr::binning_memory_resource::add_bin
向此资源添加一个 bin 分配器。
定义: binning_memory_resource.hpp:158
rmm::mr::device_memory_resource
定义: device_memory_resource.hpp:92
rmm::mr::fixed_size_memory_resource
分配单一固定大小内存块的 device_memory_resource。