Глубокое обучение Caffe Механизм управления памятью Понимание

глубокое обучение

Предыдущая статья в Цзяньшу была перемещена ^-^
Данная статья является оригинальной работой автора, если есть какие-либо недоразумения, пожалуйста, укажите на них, если необходимо процитировать, пожалуйста, укажите источник.

#Анализ управления памятью BLOB-объектов

В иерархической структуре caffe Blob играет роль управления памятью, защищая восприятие логическим кодом верхнего уровня приложения и выпуска данных, а также экранируя влияние нижележащего устройства на логику верхнего уровня.Эта статья в основном анализирует Механизм управления и практическое применение Blob Механизм запроса памяти блока SyncedMemory. Во-первых, давайте посмотрим на отношения между Blob и SyncedMemory.Схема классов выглядит следующим образом:

blob_class.jpg

На самом деле реализация всего BLOB-объекта заключается в инкапсуляции слоя в SyncedMemory, поэтому сначала необходимо проанализировать механизм реализации SyncedMemory.

##Механизм реализации SyncedMemory Целью SyncedMemory является защита восприятия кодом верхнего уровня распределения памяти различных аппаратных устройств и скрытие процесса синхронизации между CPU и GPU. В то же время, когда SyncedMemory реализуется, он принимает «ленивый» режим, то есть фактическая синхронизация приложений памяти осуществляется при ее первом использовании. Имея общее представление, разберем его подробно. Ниже приведен набор интерфейсов, предоставляемых SyncedMemory,

название Функции
cpu_data() Получить указатель данных ЦП
gpu_data() Получить указатель данных графического процессора

Реализованный код выглядит следующим образом:

const void* SyncedMemory::cpu_data() {
  to_cpu();
 return (const void*)cpu_ptr_;
}

const void* SyncedMemory::gpu_data() {
#ifdef USE_CUDA
  to_gpu();
  return (const void*)gpu_ptr_;
#else
  NO_GPU;
  return NULL;
#endif  // USE_CUDA
}

Видно, что при каждом вызове интерфейса будут выполняться операции to_cpu() и to_gpu(), так что же представляют собой функции этих двух операций, давайте взглянем на некоторые ключевые параметры в SyncedMemory:

название Функции
cpu_ptr_ указатель данных процессора
gpu_ptr_ указатель данных графического процессора
size_ Количество данных, которые должна поддерживать текущая SyncedMemory.
head_ Текущее состояние SyncedMemory

Первые три понятны, а последний особенный, он поддерживает текущее состояние SyncedMemory, которое делится на четыре состояния: UNINITIALIZED, HEAD_AT_GPU, HEAD_AT_CPU и SYNCED. Теперь давайте представим конкретный процесс.Когда to_cpu() вызывается в первый раз, head_ находится в состоянии UNINITIALIZED, тогда система вызывает метод памяти приложения ЦП для получения области памяти, а затем устанавливаетhead_ = HEAD_AT_CPU, Если в промежуточном процессе нет GPU-устройства, изменения состояния не будет.Если в середине есть код, который вызывает to_gpu(), будет обнаружено, что head_ находится в состоянии HEAD_AT_CPU.В это время синхронизация будет вызвана функция для синхронизации данных от ЦП к ГП После этого, если вернувшись к ЦП, вы также обнаружите, что head_ находится в состоянии HEAD_AT_GPU, то будет вызван соответствующий код синхронизации для синхронизации данных обратно к ЦП, а разница в приложении и переключении между ГП и ЦП экранируется с помощью параметра состояния, такого как head_.

Поэтому бизнесу верхнего уровня нужно только знать, нужны ли ему данные ЦП или ГП, а затем вызывать различные интерфейсы для завершения операции сбора данных.

##Анализ реализации BLOB-объектов Разобравшись с реализацией SyncedMemory, можно относительно просто взглянуть на Blob, поскольку он выполняет некоторую логику управления верхнего уровня и предоставляет несколько ключевых интерфейсов для внешнего мира:

название Функции
cpu_data() Получить указатель данных ЦП, содержимое данных не может быть изменено
mutable_cpu_data() Получите указатель данных ЦП, вы можете изменить содержимое данных
gpu_data() Получите указатель данных графического процессора, содержимое данных не может быть изменено
mutable_gpu_data() Получите указатель данных GPU, вы можете изменить содержимое данных
Reshape() Отрегулируйте информацию об измерении данных

Первые четыре являются инкапсуляцией cpu_data() и gpu_data() SyncedMemory, просто обязательно вызывайте относительную функцию to_cpu или to_gpu перед каждым сбором данных. Последняя функция Reshape в основном предназначена для корректировки информации о размерах и может использоваться для адаптации к различным форматам данных, поэтому предоставляются три перегруженные функции, как показано ниже:

void Blob::Reshape(const int num, const int channels,const int height, const int width);
void Blob::Reshape(const BlobShape& shape) ;
void Blob::Reshape(const vector<int>& shape);

Первые две перегруженные функции только преобразуют формат данных, а затем вызывают третью функцию, поэтомуvoid Blob::Reshape(const vector<int>& shape);Это собственно исполнитель, здесь нам нужно ввести несколько ключевых параметров в Blob:

название Функции
data_ Фактическое место хранения данных
shape_data_ Размер места хранения информации о данных (NCHW)
capacity_ Размер текущего блока данных
count_ Размер блока данных после изменения формы

Нетрудно прочитать код, чтобы обнаружить, что то, что хранится в cout_, является произведением всех измерений, то есть размера данных, которые должны быть изменены в данный момент.Весь процесс изменения формы выглядит следующим образом:

reshape.jpg

##Заканчивать Вышеизложенное является частью моего понимания Blob, я надеюсь помочь вам.