tensorflow原始碼解析之framework-allocator
1. 核心概念
allocator給出的只是記憶體分配器的介面,沒有給出具體實現。allocator_registry用單例模式實現了一個全域性的記憶體分配器註冊類,負責管理和註冊所有的記憶體分配器。
2. allocator
2.1 Allocator
Allocator是一個記憶體分配器的介面類,它規定了一個記憶體分配器需要具有哪些API。具體看程式碼:
class Allocator {public: virtual void* AllocateRaw(size_t alignment, size_t num_bytes) = 0; virtual void DeallocateRaw(void* ptr) = 0; T* Allocate(size_t num_elements); T* Allocate(size_t num_elements, const AllocationAttributes& allocation_attr); void Deallocate(T* ptr, size_t num_elements); virtual bool TracksAllocationSizes(); virtual bool ShouldAllocateEmptyTensors(); virtual size_t RequestedSize(void* ptr); virtual size_t AllocatedSize(void* ptr); virtual int64 AllocationId(void* ptr);//本次記憶體分配的編號 virtual size_t AllocatedSizeSlow(void* ptr); virtual void GetStats(AllocatorStats* stats); }
另外,Allocator除了提供申請記憶體的介面之外,還提供了為申請好的記憶體呼叫預設構造和解構函式的介面。如果在申請的時候指定了物件的型別,就可以選擇呼叫物件所屬類的構造和析構方法。Allocator提供了針對三種常用類的構造方法,分別是String,ResourceHandle,Variant。
class Allocator {public: //...private: void RunCtor(T* p, size_t n); virtual void RunStringCtor(string* p, size_t n); virtual void RunStringDtor(string* p, size_t n); virtual void RunResourceCtor(ResourceHandle* p, size_t n); virtual void RunResourceDtor(ResourceHandle* p, size_t n); virtual void RunVariantCtor(Variant* p, size_t n); virtual void RunVariantDtor(Variant* p, size_t n); }
2.2 AllocatorAttributes
不同的裝置分配記憶體的方法並不相同,那是不是各裝置只需要實現自身的記憶體分配器就可以了呢?如果在計算中每個裝置只需要用到自己的記憶體,當然是沒有問題的,但在TF中,有些情況下為了效率,GPU也需要用到CPU記憶體,比如,為了使用DMA給某些裝置傳送資料,我們仍然需要申請CPU記憶體。因此,當我們向一個裝置索要記憶體分配器時,需要給它提供一些資訊,告訴裝置我們想要申請哪種型別的記憶體,這些資訊就儲存在AllocatorAttributes類中。
struct AllocatorAttributes { void set_on_host(bool v); bool on_host() const; void set_nic_compatible(bool v); bool nic_compatible() const; void set_gpu_compatible(bool v); bool gpu_compatible() const; void set_track_sizes(bool v); bool track_sizes() const; void Merge(AllocatorAttributes other); bool IsEqualOrLessRestrictiveThan(const AllocatorAttributes& other); uint32 value = 0;//這個數值的高8位被保留為裝置相關的設定。各裝置的實現可以根據需要自行解析,為這些裝置實現的操作也需要正確的解析它}
2.3 AllocationAttributes
AllocatorAttributes很容易與另外一個類混淆,那就是AllocationAttributes。後者是為記憶體分配器的某一次具體的記憶體分配準備資訊的,而前者是為向裝置索要合適的記憶體分配器提供給裝置的,使用時機完全不一樣。
class AllocationAttributes { bool no_retry_on_failure = false; //如果首次記憶體分配失敗了,不再嘗試。 bool allocation_will_be_logged = false;//本次記憶體分配是否會被記錄}
2.4 AllocatorWrapper
有時候我們想對某個記憶體分配器進行封裝,以便在某個API上實現定製化。這時就需要用到AllocatorWrapper類,它本質上就是對Allocator類的直接封裝。
2.5 AllocatorStats
為了對某個記憶體分配器已分配的記憶體進行統計,TF還設計了一個結構,AllocatorStats。
struct AllocatorStats { int64 num_allocs;//記憶體分配次數 int64 bytes_in_use;//分配的記憶體中,當前正在使用的大小 int64 max_bytes_in_use;//使用中的記憶體大小的峰值 int64 max_alloc_size;//最大的單次記憶體分配大小 int64 bytes_limit;//當前記憶體分配器能分配的最大記憶體量,如果申請記憶體大小超過這個閾值,返回0 //...}
3. allocator_registry
3.1 AllocatorRegistry
先看一下,註冊器內部是怎樣儲存記憶體分配器的:
class AllocatorRegistry { //...private: std::vectorallocators_; //...}
其實就是把記憶體分配器儲存在一個向量裡,但並不是直接儲存記憶體分配器本身,而是對它的一個封裝,我們看下這個封裝的結構:
typedef struct { string name; int priority; Allocator* allocator; } AllocatorRegistryEntry;
除了記憶體分配器之外,這個entry裡還存放了記憶體分配器的名稱和優先順序。當我們向AllocatorRegistry請求一個記憶體分配器時,它返回的是具有最高優先順序的分配器,如果多個分配器有相同的優先順序,就返回其中的一個。
原文出處:https://www.cnblogs.com/jicanghai/p/9535808.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/430/viewspace-2813234/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- tensorflow原始碼解析之framework-resource原始碼Framework
- [原始碼解析] TensorFlow 分散式之 ClusterCoordinator原始碼分散式
- [原始碼解析] TensorFlow 分散式之 MirroredStrategy原始碼分散式
- [原始碼解析] TensorFlow 之 分散式變數原始碼分散式變數
- [原始碼解析] TensorFlow 分散式之 ParameterServerStrategy V2原始碼分散式Server
- [原始碼解析] TensorFlow 分散式之 ParameterServerStrategy V1原始碼分散式Server
- [原始碼解析] TensorFlow 分散式 DistributedStrategy 之基礎篇原始碼分散式
- [原始碼解析] TensorFlow 分散式之 MirroredStrategy 分發計算原始碼分散式
- [原始碼解析] TensorFlow 分散式環境(5) --- Session原始碼分散式Session
- [原始碼解析] TensorFlow 分散式環境(4) --- WorkerCache原始碼分散式
- Dubbo原始碼解析之SPI原始碼
- Vue原始碼解析之nextTickVue原始碼
- Flutter之Navigator原始碼解析Flutter原始碼
- Vue原始碼解析之parseVue原始碼
- jQuery原始碼解析之position()jQuery原始碼
- jQuery原始碼解析之clone()jQuery原始碼
- LevelDB 原始碼解析之 Arena原始碼
- Spring原始碼之IOC(一)BeanDefinition原始碼解析Spring原始碼Bean
- Android 原始碼分析之 EventBus 的原始碼解析Android原始碼
- YOLOv3 的 TensorFlow 實現,GitHub 完整原始碼解析YOLOGithub原始碼
- LevelDB 原始碼解析之 Varint 編碼原始碼
- spring 原始碼解析之開篇Spring原始碼
- Java集合之Hashtable原始碼解析Java原始碼
- jQuery原始碼解析之replaceWith()/unwrap()jQuery原始碼
- Java集合之ArrayList原始碼解析Java原始碼
- JDK原始碼解析系列之objectJDK原始碼Object
- Drill-on-YARN之原始碼解析Yarn原始碼
- @angular/forms 原始碼解析之 ValidatorsAngularORM原始碼
- Java集合之LinkedList原始碼解析Java原始碼
- Spring原始碼解析之BeanFactoryPostProcessor(一)Spring原始碼Bean
- Spring原始碼解析之ConfigurationClassPostProcessor(一)Spring原始碼
- Spring原始碼解析之BeanFactoryPostProcessor(三)Spring原始碼Bean
- Spring原始碼解析之ConfigurationClassPostProcessor(二)Spring原始碼
- Spring原始碼解析之ConfigurationClassPostProcessor(三)Spring原始碼
- 【spring原始碼系列】之【xml解析】Spring原始碼XML
- Spring原始碼解析之BeanFactoryPostProcessor(二)Spring原始碼Bean
- [原始碼解析] TensorFlow 分散式環境(8) --- 通訊機制原始碼分散式
- [原始碼解析] TensorFlow 分散式環境(1) --- 總體架構原始碼分散式架構