Shared gpu memory usage что это

Выделение памяти под встроенную видеокарту: как увеличить видеопамять у интегрированных IntelHD, Intel Iris Xe и AMD Ryzen Vega (UMA Frame Buffer Size)

Shared gpu memory usage что это. Uvelichivaem videopamyat. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Uvelichivaem videopamyat. картинка Shared gpu memory usage что это. картинка Uvelichivaem videopamyatДоброго времени!

В последнее время снискали большую популярность интегрированные (их еще называют встроенными ) видеокарты IntelHD, Intel Iris Xe, и AMD Ryzen Vega. Последних версий уже с лихвой хватает для многих не слишком требовательных игр (что, конечно, радует — т.к. получается хорошая такая экономия на покупке внешней видеокарты)!

Однако, есть один нюанс : видеопамять для этих карт выделяется из ОЗУ (RAM). По умолчанию эта операция «выделения» происходит автоматически (без вашего участия), что не во всех случаях оптимально (например, вы можете столкнуться с ошибками во время запуска игр. ).

Разумеется, было бы не плохо вручную отрегулировать выделение памяти под интегрированную карту (в большинстве случаев стоит вопрос ее увеличения ).

И так, перейдем ближе к теме.

Можно ли разогнать встроенные видеокарты Intel HD и AMD Radeon? За счет чего поднять их производительность

Shared gpu memory usage что это. uskwin. Shared gpu memory usage что это фото. Shared gpu memory usage что это-uskwin. картинка Shared gpu memory usage что это. картинка uskwin

Как увеличить видеопамять: по шагам

ШАГ 1: зачем это нужно

Вообще, если у вас все корректно работает, нет притормаживаний, ничего не зависает и не вылетает с ошибками — то вам, скорее всего, это и не нужно.

Однако, есть ситуации, когда без этого никак:

Shared gpu memory usage что это. 3DMark Sky Driver 8GB Ram dual. Shared gpu memory usage что это фото. Shared gpu memory usage что это-3DMark Sky Driver 8GB Ram dual. картинка Shared gpu memory usage что это. картинка 3DMark Sky Driver 8GB Ram dual

3DMark Sky Driver (8GB Ram, dual) — производительность в зависимости от выделенной памяти для интегрированной видеокарты AMD Ryzen Vega 11 (Ryzen 5 2400G)

Примечание!

👉 Если у вас количество ОЗУ 8 ГБ (и более) — то большинство современных материнских плат по умолчанию устанавливают для встроенной видеокарты номинальные 1024 МБ (которых пока достаточно для норм. работы).

👉 Не могу не отметить, что если у вас на борту меньше 6 ГБ ОЗУ — то выставлять для интегрированной карты больше 1 ГБ памяти крайне не рекомендуется! Это отрицательно сказывается на общей производительности ПК/ноутбука.

ШАГ 2: как узнать текущий объем видеопамяти

👉 Вариант 1

Это универсальный вариант, работающий во всех популярных версиях Windows 7/8/10.

Сначала необходимо нажать сочетание кнопок Win+R — в окне «Выполнить» ввести команду dxdiag и кликнуть по OK.

Shared gpu memory usage что это. WinR. Shared gpu memory usage что это фото. Shared gpu memory usage что это-WinR. картинка Shared gpu memory usage что это. картинка WinR

Далее откроется средство диагностики DirectX — во вкладке «Экран» среди прочих характеристик устройства вы найдете размер видеопамяти (👇).

Shared gpu memory usage что это. Videopamyat 1009 MB. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Videopamyat 1009 MB. картинка Shared gpu memory usage что это. картинка Videopamyat 1009 MB

Видеопамять 1009 МБ

👉 Вариант 2

Shared gpu memory usage что это. Dop. parametryi displeya. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Dop. parametryi displeya. картинка Shared gpu memory usage что это. картинка Dop. parametryi displeya

Доп. параметры дисплея

Shared gpu memory usage что это. Svoystva videoadaptera. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Svoystva videoadaptera. картинка Shared gpu memory usage что это. картинка Svoystva videoadaptera

Shared gpu memory usage что это. Ispolzuetsya videopamyati. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Ispolzuetsya videopamyati. картинка Shared gpu memory usage что это. картинка Ispolzuetsya videopamyati

👉 Вариант 3

Этот вариант также актуален для ОС Windows 10.

Shared gpu memory usage что это. Dispetcher zadach Windows 10. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Dispetcher zadach Windows 10. картинка Shared gpu memory usage что это. картинка Dispetcher zadach Windows 10

ШАГ 3: как вручную установить размер выделения памяти под встроенную видеокарту

Через BIOS/UEFI

Только через настройки BIOS (в принципе) и можно изменить размер выделяемой памяти для интегрированной карты (в редких случаях можно попытаться «обмануть» игры через реестр).

И так, сначала необходимо 👉 войти в BIOS (ссылка на инструкцию в помощь).

Далее нужно перейти в раздел «Configuration» (в некоторых BIOS за это отвечает раздел «Advanced» ).

Shared gpu memory usage что это. Linovo Setup Utility glavnoe okno. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Linovo Setup Utility glavnoe okno. картинка Shared gpu memory usage что это. картинка Linovo Setup Utility glavnoe okno

Затем нам нужно найти один из следующих параметров (прим.: в разных версиях BIOS он называется по-своему) :

На скриншоте ниже приведен параметр «iGPU Configuration» — необходимо отключить авто-режим!

Shared gpu memory usage что это. Otklyuchaem Auto rezhim. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Otklyuchaem Auto rezhim. картинка Shared gpu memory usage что это. картинка Otklyuchaem Auto rezhim

Отключаем Auto режим

А после вручную задать параметр «UMA Frame Buffer Size» — это и есть размер выделяемой видеопамяти (в моем примере можно выбрать от 256 МБ до 2 ГБ 👇).

Shared gpu memory usage что это. UMA Frame Buffer Size stavim 2 GB. Shared gpu memory usage что это фото. Shared gpu memory usage что это-UMA Frame Buffer Size stavim 2 GB. картинка Shared gpu memory usage что это. картинка UMA Frame Buffer Size stavim 2 GB

UMA Frame Buffer Size — ставим 2 GB

Shared gpu memory usage что это. Advanced. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Advanced. картинка Shared gpu memory usage что это. картинка Advanced

Advanced / настройки BIOS / American Megatrends

Shared gpu memory usage что это. DVMT stavim na. Shared gpu memory usage что это фото. Shared gpu memory usage что это-DVMT stavim na. картинка Shared gpu memory usage что это. картинка DVMT stavim na

DVMT ставим на Maximum

Еще один пример для более старой версии American Megatrends см. ниже. 👇

Shared gpu memory usage что это. Share Memory Size vyidelenie pamyati videosisteme. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Share Memory Size vyidelenie pamyati videosisteme. картинка Shared gpu memory usage что это. картинка Share Memory Size vyidelenie pamyati videosisteme

Через настройки реестра (опционально для IntelHD)

Этот способ поможет только «перехитрить» некоторые игры, которые могут вылетать с ошибками после запуска (т.к. у вас якобы недостаточно видеопамяти). Т.е. игра будет «считать», что размер памяти видеокарты у вас больше, чем есть на самом деле.

Причем, хочу отметить, что срабатывает он не всегда (но всё же, вдруг. ).

И так, для начала нужно 👉 открыть редактор реестра — нажать Win+R, и использовать команду regedit.

Shared gpu memory usage что это. regedit otkryit redaktor reestra. Shared gpu memory usage что это фото. Shared gpu memory usage что это-regedit otkryit redaktor reestra. картинка Shared gpu memory usage что это. картинка regedit otkryit redaktor reestra

regedit — открыть редактор реестра

Далее в редакторе нужно создать раздел «GMM» в нижеприведенной ветке:

Shared gpu memory usage что это. Sozdat razdel GMM. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Sozdat razdel GMM. картинка Shared gpu memory usage что это. картинка Sozdat razdel GMM

Создать раздел GMM

После, в разделе «GMM» создать строковый параметр с именем «DedicatedSegmentSize» (без кавычек).

Shared gpu memory usage что это. Sozdat strokovyiy parametr. Shared gpu memory usage что это фото. Shared gpu memory usage что это-Sozdat strokovyiy parametr. картинка Shared gpu memory usage что это. картинка Sozdat strokovyiy parametr

Создать строковый параметр

Далее открыть его и задать значение выделяемой памяти (судя по тестам, способ актуален и работает для значений от 0 до 512).

Источник

CUDA: Работа с памятью. Часть II.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loaderОсновная тема этой части – оптимизация работы с глобальной памятью при программировании GPU.

У GPU есть ряд особенностей, игнорирование которых может стоить многократной потери производительности при использовании глобальной памяти. Но если учесть все тонкости, то можно получить действительно эффективные CUDA-программы.

Что не так с глобальной памятью?

Объем глобальной памяти самый большой из всех типов памяти, но в тоже время эта память – самая медлительная по техническим характеристикам: скорости считывания и записи.

В предыдущей части я рассматривал пример транспонирования матрицы. Для повышения производительности использовался буфер разделяемой памяти, что позволило увеличить производительность почти в четыре раза. Но было достаточно страно видеть это увеличение при лишнем посреднике. Секрет же кроется в правильном обращении к глобальной памяти.

Можно выделить два способа оптимизации в работе с глобальной памятью: выравнивание размеров используемых типов и использование объединенных запросов.

Выравнивание размеров используемых типов

Выравнивание типа данных позволяет скомпилировать запрос в глобальную память в одну команду GPU, в противном случае компилятор сгенерирует дополнительный код, что может значительно понизить производительность. Для оптимальной производительности тип данных должен иметь размерность 4, 8 или 16 байт.

Если размер типа не соответствует 4, 8 или 16 байтам, то лучше использовать тип большей размерности или произвести выравнивание с помощью ключевого слова __align__(размер выравнивания).

Пример оптимизации при использовании встроенных CUDA-типов.

Размер типа int3 – 12 байт, доступ к памяти будет не оптимальным:

Лучше использовать тип int4 (16 байтов), даже если четвертый компонент вам не нужен:

В случае работы со структурами необходимо использовать ключевое слово __align__, которое позволяет выравнивать тип по заданному размеру.

Пример выравнивания размера структуры.

До выравнивания размер структуры vector3 составит 12 байт:

На консоль выведется число 12.

После выравнивания размер vector3 составит 16 байт:

На консоль выведется число 16.

Использование объединеных запросов

Куда больший прирост производительности можно получить при объединении большого количества запрос в глобальную память в один (иногда запросы назвают транзакциями). В документации nVidia это назвается coalescing global memory accesses. Но, перед тем, как перейти к непосредственному обсуждению того, что необходимо для объединения запросов в память, необходимо знать пару дополнительных вещей о работе GPU.

Для контроля исполнения работы нитей GPU использует так называемый warp. С программной точки зрения warp представляет пул нитей. Именно в пределах этого warp’а происходит параллельная работа нитей, которые были запрошены при вызове ядра, именно в warp’е нити могут взаимодействовать между собой. Размер warp’а для всех GPU составляет 32, то есть параллельно в warp’е исполняются только 32 нити. Одновременно на GPU можно запустить несколько warp’ов, это количество определяется размерами доступной регистровой и разделяемой памяти. Другая интересная особенность, что для доступа к памяти используется half-warp, то есть в начале к памяти обращаются первые 16 нитей, а затем вторая половина из 16 нитей. Почему доступ происходи т именно так, я точно сказать не могу, могу лишь предположить, что это связано с первичными задачами GPU – обработкой графики.

Теперь рассмотрим требования, необходимые для объединения запросов в глобальную память. Не забываем, что обращение к памяти происходит через half-warp.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader
Рис. 1. Запросы, дающие объединение при обращении к памяти

На рис. 1 приведены примеры запросов к глобальной памяти, которые дают объединение в одну транзакцию. Слева выполнены все условия: каждый поток из half-warp’а обращается к соответствующему по порядку 32-битному слову, адрес начала памяти выровнен по размеру блока транзакции (16 нитей * 4 байт = 64 байта). Справа приведен пример, когда некоторые потоки из блока вообще не обращаются к соответствующим им словам в памяти.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader
Рис. 2. Запросы, не дающие объединение при обращении к памяти

На рис. 2 приведены примеры, которые не дают объединения при обращении к глобалной памяти. Слева не выполнены условие обращения нитей соответствующим словам в памяти. Справа не выполнено условие по выравниванию адреса памяти по размеру блока. В результате: вместо одной объединеной транзакции получаем по 16 отдельных, по одной на каждый поток half-warp’а.

Структуры массивов или массивы структур?

Пару слов стоит уделить вопросу по работе со структурами и как при этом добиться повышения производительности. Если есть необходимость использования массива структур, то лучше создать отдельные массивы компонентов структуры, что позволит уменьшить количество запросов в глобальную память за счет объединений.

Неэффективная работа с глобальной памятью:

__device__ vec3 data[SIZE];

Эффективнее использовать отдельные массивы:

__device__ float x[SIZE];
__device__ float y[SIZE];
__device__ float z[SIZE];

В первом случае использования массива векторов для обращения к каждому полю структуры необходим отдельный запрос в память, во втором случае за счет объединения достаточно 3 запросов для каждого half-warp’а. В среднем, этот подход позволяет увеличить производительность в 2 раза.

Заключение

В заключение всего выше сказанного хочу дать самый важный совет при работе с памятью в CUDA:

НИКОГДА НЕ ПЫТАЙТЕСЬ ИЗМЕНЯТЬ ЗНАЧЕНИЕ ОДНОЙ ЯЧЕЙКИ ПАМЯТИ НЕСКОЛЬКИМИ НИТЯМИ ОДНОВРЕМЕННО.

Это самая частая ошибка в многопоточном программировании. На самом деле CUDA не гарантирует атомарного доступа для каждой нити к определенной области памяти, поэтому результаты могут получиться не совсем такими, как ожидается. Хотя атомарные операции в CUDA и существуют, лучше использовать концепцию неизменяемых данных и сохранять результаты расчетов в новых объектах, которые и передавать на следующие этапы расчетов.

Источник

CUDA: Работа с памятью. Часть I.

В процессе работы с CUDA я практически не касался вопросов об использовании памяти видеокарты. Настало время убрать этот пробел.

Так как тема весьма объемная, то я решил разделить её на несколько частей. В этой части я расскажу об основных видах памяти, доступных на видеокарте и приведу пример, как влияет выбор типа памяти на производительность вычислений на GPU.

Видеокарта и типы памяти

При использовании GPU разработчику доступно несколько видов памяти: регистры, локальная, глобальная, разделяемая, константная и текстурная память. Каждая из этих типов памяти имеет определенное назначение, которое обуславливается её техническими параметрами (скорость работы, уровень доступа на чтение и запись). Иерархия типов памяти представлена на рис. 1.

Пример использования разделяемой памяти

Чуть выше я вкратце рассказал о различных типах памяти, которые доступны при программировании GPU. Теперь я хочу привести пример использования разделяемой памяти при операции транспонирования матрицы.

Перед тем, как приступить к написанию основного кода, приведу небольшой способ отладки. Как известно, функции из CUDA runtime API могут возвращать различные коды ошибок, но в предыдущий раз я ни как это не учитывал. Чтобы упростить себе жизнь можно использовать следующий макрос для отлова ошибок:

Как видно, в случае, если определена переменная среды CUDA_DEBUG, происходит проверка кода ошибки и выводиться информация о файле и строке, где она произошла. Эту переменную можно включить при компиляции под отладку и отключить при компиляции под релиз.

Приступаем к основной задаче.

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

if ((xIndex //Линейный индекс элемента строки исходной матрицы
int inputIdx = xIndex + width * yIndex;

//Линейный индекс элемента столбца матрицы-результата
int outputIdx = yIndex + height * xIndex;

Данная функция просто копирует строки исходной матрицы в столбцы матрицы-результата. Единственный сложный момент – это определение индексов элементов матриц, здесь необходимо помнить, что при вызове ядра может быть использованы различные размерности блоков и грида, для этого и используются встроенные переменные blockDim, blockIdx.

Пишем функцию транспонирования, которая использует разделяемую память:

int xIndex = blockIdx.x * blockDim.x + threadIdx.x;
int yIndex = blockIdx.y * blockDim.y + threadIdx.y;

if ((xIndex // Линейный индекс элемента строки исходной матрицы
int idx = yIndex * width + xIndex;

//Копируем элементы исходной матрицы
temp[threadIdx.y][threadIdx.x] = inputMatrix[idx];
>

//Синхронизируем все нити в блоке
__syncthreads();

xIndex = blockIdx.y * blockDim.y + threadIdx.x;
yIndex = blockIdx.x * blockDim.x + threadIdx.y;

if ((xIndex // Линейный индекс элемента строки исходной матрицы
int idx = yIndex * height + xIndex;

В этой функции я использую разделяемую память в виде двумерного массива.
Как уже было сказано, адресация разделяемой памяти в пределах одного блока одинакова для всех потоков, поэтому, чтобы избежать коллизий при доступе и записи, каждому элементу в массиве соответствует одна нить в блоке.
После копирования элементов исходной матрицы в буфер temp, вызывается функция __syncthreads. Эта функция синхронизирует потоки в пределах блока. Её отличие от других способов синхронизации заключаеться в том, что она выполняеться только на GPU.
В конце происходит копирование сохраненных элементов исходной матрицы в матрицу-результат, в соответствии с правилом транспонирования.
Может показаться, что эта функция должна выполняться медленне, чем её версия без разделяемой памяти, где нет никаких посредников. Но на самом деле копирование из глобальной памяти в глобальную работает значительно медленее, чем связка глобальная память – разделяемая память – глобальная память.
Хочу заметить, что проверять границы массивов матриц стоит вручную, в GPU нет аппаратных средств для слежения за границами массивов.

Ну и напоследок напишем функцию транспонирования, которая исполняется только на CPU:

Теперь необходимо сгенерировать данные для расчетов, скопировать их с хоста на девайс, в случае использования GPU, произвести замеры производительности и очистить ресурсы.
Так как эти этапы примерно такие же, что я описывал в предыдущий раз, то привожу этого фрагмента сразу:

#define GPU_SLOW 1
#define GPU_FAST 2
#define CPU 3

#define ITERATIONS 20 //Количество нагрузочных циклов

__host__ int main()
<
int width = 2048; //Ширина матрицы
int height = 1536; //Высота матрицы

int matrixSize = width * height;
int byteSize = matrixSize * sizeof ( float );

//Выделяем память под матрицы на хосте
float * inputMatrix = new float [matrixSize];
float * outputMatrix = new float [matrixSize];

//Выделяем глобальную память для храния данных на девайсе
CUDA_CHECK_ERROR(cudaMalloc(( void **)&devInputMatrix, byteSize));
CUDA_CHECK_ERROR(cudaMalloc(( void **)&devOutputMatrix, byteSize));

//Копируем исходную матрицу с хоста на девайс
CUDA_CHECK_ERROR(cudaMemcpy(devInputMatrix, inputMatrix, byteSize, cudaMemcpyHostToDevice));

//Конфигурация запуска ядра
dim3 gridSize = dim3(width / BLOCK_DIM, height / BLOCK_DIM, 1);
dim3 blockSize = dim3(BLOCK_DIM, BLOCK_DIM, 1);

cudaEvent_t start;
cudaEvent_t stop;

//Создаем event’ы для синхронизации и замера времени работы GPU
CUDA_CHECK_ERROR(cudaEventCreate(&start));
CUDA_CHECK_ERROR(cudaEventCreate(&stop));

//Отмечаем старт расчетов на GPU
cudaEventRecord(start, 0);

if (mode == GPU_SLOW) //Используеться функция без разделяемой памяти
<
for ( int i = 0; i >>(devInputMatrix, devOutputMatrix, width, height);
>
>
else if (mode == GPU_FAST) //Используеться функция с разделяемой памятью
<
for ( int i = 0; i >>(devInputMatrix, devOutputMatrix, width, height);
>
>

//Отмечаем окончание расчета
cudaEventRecord(stop, 0);

float time = 0;
//Синхронизируемя с моментом окончания расчетов
cudaEventSynchronize(stop);
//Рассчитываем время работы GPU
cudaEventElapsedTime(&time, start, stop);

//Копируем результат с девайса на хост
CUDA_CHECK_ERROR(cudaMemcpy(outputMatrix, devOutputMatrix, byteSize, cudaMemcpyDeviceToHost));

//
//Чистим ресурсы на видеокарте
//

//Чистим память на хосте
delete[] inputMatrix;
delete[] outputMatrix;

В случае если расчеты выполняются только на CPU, то для замера времени расчетов используется функция GetTickCount(), которая подключается из windows.h. Для замера времени расчетов на GPU используеться функция cudaEventElapsedTime, прототип которой имеет следующий вид:

Так же я записываю исходную матрицу и результат в файлы через функцию printMatrixToFile. Чтобы удостовериться, что результаты верны. Код этой функции следующий:

Если матрицы очень большие, то вывод данных в файлы может сильно замедлить выполнение программы.

Заключение

В процессе тестирования я использовал матрицы размерностью 2048 * 1536= 3145728 элементов и 20 итераций в нагрузочных циклах. После результатов замеров у меня получились следующие результаты (рис. 2).

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader
Рис. 2. Время расчетов. (меньше –лучше).

Как видно, GPU версия с разделяемой памятью выполняется почти в 20 раз быстрее, чем версия на CPU. Так же стоит отметить, что при использовании разделяемой памяти расчет выполняется примерно в 4 раза быстрее, чем без неё.
В своем примере я не учитываю время копирования данных с хоста на девайс и обратно, но в реальных приложениях их так же необходимо брать в расчет. Количество перемещений данных между CPU и GPU по-возможности необходимо свести к минимуму.

Источник

Анализ производительности ВМ в VMware vSphere. Часть 2: Memory

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

В этой статье поговорим про счетчики производительности оперативной памяти (RAM) в vSphere.
Вроде бы с памятью все более однозначно, чем с процессором: если на ВМ возникают проблемы с производительностью, их сложно не заметить. Зато если они появляются, справиться с ними гораздо сложнее. Но обо всем по порядку.

Немного теории

Оперативная память виртуальных машин берется из памяти сервера, на которых работают ВМ. Это вполне очевидно:). Если оперативной памяти сервера не хватает для всех желающих, ESXi начинает применять техники оптимизации потребления оперативной памяти (memory reclamation techniques). В противном случае операционные системы ВМ падали бы с ошибками доступа к ОЗУ.

Какие техники применять ESXi решает в зависимости от загруженности оперативной памяти:

Состояние памятиГраницаДействия
High400% от minFreeПосле достижения верхней границы, большие страницы памяти разбиваются на маленькие (TPS работает в стандартном режиме).
Clear100% от minFreeБольшие страницы памяти разбиваются на маленькие, TPS работает принудительно.
Soft64% от minFreeTPS + Balloon
Hard32% от minFreeTPS + Compress + Swap
Low16% от minFreeCompress + Swap + Block

minFree — это оперативная память, необходимая для работы гипервизора.

До ESXi 4.1 включительно minFree по умолчанию было фиксированным — 6% от объема оперативной памяти сервера (процент можно было поменять через опцию Mem.MinFreePct на ESXi). В более поздних версиях из-за роста объемов памяти на серверах minFree стало рассчитываться исходя из объема памяти хоста, а не как фиксированное процентное значение.

Значение minFree (по умолчанию) считается следующим образом:

Процент памяти, резервируемый для minFreeДиапазон памяти
6%0-4 Гбайт
4%4-12 Гбайт
2%12-28 Гбайт
1%Оставшаяся память

Например, для сервера со 128 Гбайт RAM значение MinFree будет таким:
MinFree = 245,76 + 327,68 + 327,68 + 1024 = 1925,12 Мбайт = 1,88 Гбайт
Фактическое значение может отличаться на пару сотен МБайт, это зависит от сервера и оперативной памяти.

Процент памяти, резервируемый для minFreeДиапазон памятиЗначение для 128 Гбайт
6%0-4 Гбайт245,76 Мбайт
4%4-12 Гбайт327,68 Мбайт
2%12-28 Гбайт327,68 Мбайт
1%Оставшаяся память (100 Гбайт)1024 Мбайт

Обычно для продуктивных стендов нормальным можно считать только состояние High. Для стендов для тестирования и разработки приемлемыми могут быть состояния Clear/Soft. Если оперативной памяти на хосте осталось менее 64% MinFree, то у ВМ, работающих на нем, точно наблюдаются проблемы с производительностью.

В каждом состоянии применяются определенные memory reclamation techniques начиная с TPS, практически не влияющего на производительность ВМ, заканчивая Swapping’ом. Расскажу про них подробнее.

Transparent Page Sharing (TPS). TPS — это, грубо говоря, дедупликация страниц оперативной памяти виртуальных машин на сервере.

ESXi ищет одинаковые страницы оперативной памяти виртуальных машин, считая и сравнивая hash-сумму страниц, и удаляет дубликаты страниц, заменяя их ссылками на одну и ту же страницу в физической памяти сервера. В результате потребление физической памяти снижается и можно добиться некоторой переподписки по памяти практически без снижения производительности.

Shared gpu memory usage что это. ulfz1i0bomyhsarceziylov o6i. Shared gpu memory usage что это фото. Shared gpu memory usage что это-ulfz1i0bomyhsarceziylov o6i. картинка Shared gpu memory usage что это. картинка ulfz1i0bomyhsarceziylov o6i
Источник

Данный механизм работает только для страниц памяти размером 4 Кбайт (small pages). Страницы размером 2 МБайт (large pages) гипервизор дедуплицировать даже не пытается: шанс найти одинаковые страницы такого размера не велик.

По умолчанию ESXi выделяет память большим страницам. Разбивание больших страниц на маленькие начинается при достижении порога состояния High и происходит принудительно, когда достигается состояние Clear (см. таблицу состояний гипервизора).

Если же вы хотите, чтобы TPS начинал работу, не дожидаясь заполнения оперативной памяти хоста, в Advanced Options ESXi нужно установить значение “Mem.AllocGuestLargePage” в 0 (по умолчанию 1). Тогда выделение больших страниц памяти для виртуальных машин будет отключено.

С декабря 2014 во всех релизах ESXi TPS между ВМ по умолчанию отключен, так как была найдена уязвимость, теоретически позволяющая получить из одной ВМ доступ к оперативной памяти другой ВМ. Подробности тут. Информация про практическую реализацию эксплуатации уязвимости TPS мне не встречалось.

Политика TPS контролируется через advanced option “Mem.ShareForceSalting” на ESXi:
0 — Inter-VM TPS. TPS работает для страниц разных ВМ;
1 – TPS для ВМ с одинаковым значением “sched.mem.pshare.salt” в VMX;
2 (по умолчанию) – Intra-VM TPS. TPS работает для страниц внутри ВМ.

Однозначно имеет смысл выключать большие страницы и включать Inter-VM TPS на тестовых стендах. Также это можно использовать для стендов с большим количеством однотипных ВМ. Например, на стендах с VDI экономия физической памяти может достигать десятков процентов.

Memory Ballooning. Ballooning уже не такая безобидная и прозрачная для операционной системы ВМ техника, как TPS. Но при грамотном применении с Ballooning’ом можно жить и даже работать.

Вместе с Vmware Tools на ВМ устанавливается специальный драйвер, называемый Balloon Driver (он же vmmemctl). Когда гипервизору начинает не хватать физической памяти и он переходит в состояние Soft, ESXi просит ВМ вернуть неиспользуемую оперативную память через этот Balloon Driver. Драйвер в свою очередь работает на уровне операционной системы и запрашивает свободную память у нее. Гипервизор видит, какие страницы физической памяти занял Balloon Driver, забирает память у виртуальной машины и возвращает хосту. Проблем с работой ОС не возникает, так как на уровне ОС память занята Balloon Driver’ом. По умолчанию Balloon Driver может забрать до 65% памяти ВМ.

Если на ВМ не установлены VMware Tools или отключен Ballooning (не рекомендую, но есть KB:), гипервизор сразу переходит к более жестким техникам отъема памяти. Вывод: следите, чтобы VMware Tools на ВМ были.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader
Работу Balloon Driver’а можно проверить из ОС через VMware Tools.

Memory Compression. Данная техника применяется, когда ESXi доходит до состояния Hard. Как следует из названия, ESXi пытается сжать 4 Кбайт страницы оперативной памяти до 2 Кбайт и таким образом освободить немного места в физической памяти сервера. Данная техника значительно увеличивает время доступа к содержимому страниц оперативной памяти ВМ, так как страницу надо предварительно разжать. Иногда не все страницы удается сжать и сам процесс занимает некоторое время. Поэтому данная техника на практике не очень эффективна.

Memory Swapping. После недолгой фазы Memory Compression ESXi практически неизбежно (если ВМ не уехали на другие хосты или не выключились) переходит к Swapping’у. А если памяти осталось совсем мало (состояние Low), то гипервизор также перестает выделять ВМ страницы памяти, что может вызвать проблемы в гостевых ОС ВМ.

В отличие от Ballooning’а, когда у ВМ отбираются неиспользуемые страницы, при Swapping’e на диск могут переехать страницы, которые активно используются ОС или приложениями внутри ВМ. В результате производительность ВМ падает вплоть до подвисания. ВМ формально работает и ее как минимум можно правильно отключить из ОС. Если вы будете терпеливы 😉

Если ВМ ушли в Swap — это нештатная ситуация, которую по возможности лучше не допускать.

Основные счетчики производительности памяти виртуальной машины

Вот мы и добрались до главного. Для мониторинга состояния памяти в ВМ есть следующие счетчики:

Active — показывает объем оперативной памяти (Кбайт), к которому ВМ получила доступ в предыдущий период измерения.

Usage — то же, что Active, но в процентах от сконфигурированной оперативной памяти ВМ. Рассчитывается по следующей формуле: active ÷ virtual machine configured memory size.
Высокий Usage и Active, соответственно, не всегда является показателем проблем производительности ВМ. Если ВМ агрессивно использует память (как минимум, получает к ней доступ), это не значит, что памяти не хватает. Скорее это повод посмотреть, что происходит в ОС.
Есть стандартный Alarm по Memory Usage для ВМ:

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

Shared — объем оперативной памяти ВМ, дедуплицированной с помощью TPS (внутри ВМ или между ВМ).

Granted — объем физической памяти хоста (Кбайт), который был отдан ВМ. Включает Shared.

Consumed (Granted — Shared) — объем физической памяти (Кбайт), которую ВМ потребляет с хоста. Не включает Shared.

Если часть памяти ВМ отдается не из физической памяти хоста, а из swap-файла или память отобрана у ВМ через Balloon Driver, данный объем не учитывается в Granted и Consumed.
Высокие значения Granted и Consumed — это совершенно нормально. Операционная система постепенно забирает память у гипервизора и не отдает обратно. Со временем у активно работающей ВМ значения данных счетчиков приближается к объему сконфигурированной памяти, и там остаются.

Zero — объем оперативной памяти ВМ (Кбайт), который содержит нули. Такая память считается гипервизором свободной и может быть отдана другим виртуальным машинам. После того, как гостевая ОС получила записала что-либо в зануленную память, она переходит в Consumed и обратно уже не возвращается.

Reserved Overhead — объем оперативной памяти ВМ, (Кбайт) зарезервированный гипервизором для работы ВМ. Это небольшой объем, но он обязательно должен быть в наличии на хосте, иначе ВМ не запустится.

Balloon — объем оперативной памяти (Кбайт), изъятой у ВМ с помощью Balloon Driver.

Compressed — объем оперативной памяти (Кбайт), которую удалось сжать.

Swapped — объем оперативной памяти (Кбайт), которая за неимением физической памяти на сервере переехала на диск.
Balloon и остальные счетчики memory reclamation techniques равны нулю.

Вот так выглядит график со счетчиками Memory нормально работающей ВМ со 150 ГБ оперативной памяти.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

На графике ниже у ВМ явные проблемы. Под графиком видно, что для данной ВМ были использованы все описанные техники работы с оперативной памятью. Balloon для данной ВМ сильно больше, чем Consumed. По факту ВМ скорее мертва, чем жива.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

ESXTOP

Как и с CPU, если хотим оперативно оценить ситуацию на хосте, а также ее динамику с интервалом до 2 секунд, стоит воспользоваться ESXTOP.

Экран ESXTOP по Memory вызывается клавишей «m» и выглядит следующим образом (выбраны поля B,D,H,J,K,L,O):

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

Интересными для нас будут следующие параметры:

Mem overcommit avg — среднее значение переподписки по памяти на хосте за 1, 5 и 15 минут. Если выше нуля, то это повод посмотреть, что происходит, но не всегда показатель наличия проблем.

В строках PMEM/MB и VMKMEM/MB — информация о физической памяти сервера и памяти доступной VMkernel. Из интересного здесь можно увидеть значение minfree (в МБайт), состояние хоста по памяти (в нашем случае, high).

В строке NUMA/MB можно увидеть распределение оперативной памяти по NUMA-нодам (сокетам). В данном примере распределение неравномерное, что в принципе не очень хорошо.

Далее идет общая статистика по серверу по memory reclamation techniques:

PSHARE/MB — это статистика TPS;

SWAP/MB — статистика использования Swap;

ZIP/MB — статистика компрессии страниц памяти;

MEMCTL/MB — статистика использования Balloon Driver.

По отдельным ВМ нас может заинтересовать следующая информация. Имена ВМ я скрыл, чтобы не смущать аудиторию:). Если метрика ESXTOP аналогична счетчику в vSphere, привожу соответствующий счетчик.

MEMSZ — объем памяти, сконфигурированный на ВМ (МБ).
MEMSZ = GRANT + MCTLSZ + SWCUR + untouched.

GRANT — Granted в МБайт.

TCHD — Active в МБайт.

MCTL? — установлен ли на ВМ Balloon Driver.

MCTLSZ — Balloon в МБайт.

MCTLGT — объем оперативной памяти (МБайт), который ESXi хочет изъять у ВМ через Balloon Driver (Memctl Target).

MCTLMAX — максимальный объем оперативной памяти (МБайт), который ESXi может изъять у ВМ через Balloon Driver.

SWCUR — текущий объем оперативной памяти (МБайт), отданный ВМ из Swap-файла.

SWGT — объем оперативной памяти (МБайт), который ESXi хочет отдавать ВМ из Swap-файла (Swap Target).

Также через ESXTOP можно посмотреть более подробную информацию про NUMA-топологию ВМ. Для этого нужно выбрать поля D,G:

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

NHN – NUMA узлы, на которых расположена ВМ. Здесь можно сразу заметить wide vm, которые не помещаются на один NUMA узел.

NRMEM – сколько мегабайт памяти ВМ берет с удаленного NUMA узла.

NLMEM – сколько мегабайт памяти ВМ берет с локального NUMA узла.

N%L – процент памяти ВМ на локальном NUMA узле (если меньше 80% — могут возникнуть проблемы с производительностью).

Memory на гипервизоре

Если счетчики CPU по гипервизору обычно не представляют особого интереса, то с памятью ситуация обратная. Высокий Memory Usage на ВМ не всегда говорит о наличие проблемы с производительностью, а вот высокий Memory Usage на гипервизоре, как раз запускает работу техник управления памятью и вызывает проблемы с производительностью ВМ. За алармами Host Memory Usage надо следить и не допускать попадания ВМ в Swap.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

Unswap

Если ВМ попала в Swap, ее производительность сильно снижается. Следы Ballooning’а и компрессии быстро исчезают после появления свободной оперативной памяти на хосте, а вот возвращаться из Swap в оперативную память сервера виртуальная машина совсем не торопится.
До версии ESXi 6.0 единственным надежным и быстрым способ вывода ВМ из Swap была перезагрузка (если точнее выключение/включение контейнера). Начиная с ESXi 6.0 появился хотя и не совсем официальный, но рабочий и надежный способ вывести ВМ из Swap. На одной из конференций мне удалось пообщаться с одним из инженеров VMware, отвечающим за CPU Scheduler. Он подтвердил, что способ вполне рабочий и безопасный. В нашем опыте проблем с ним также замечено не было.

Собственно команды для вывода ВМ из Swap описал Duncan Epping. Не буду повторять подробное описание, просто приведу пример ее использования. Как видно на скриншоте, через некоторое время после выполнения указанной команд Swap на ВМ исчезает.

Shared gpu memory usage что это. image loader. Shared gpu memory usage что это фото. Shared gpu memory usage что это-image loader. картинка Shared gpu memory usage что это. картинка image loader

Советы по управлению оперативной памятью на ESXi

Напоследок приведу несколько советов, которые помогут вам избежать проблем с производительностью ВМ из-за оперативной памяти:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *