Является ли использование cudaDeviceReset () после вычислений нормальным способом использования графического процессора из Matlab?Я не могу использовать вычисления на GPU в последней версии Matlab, потому что мой GPU не поддерживает Compute Capability 1.3+, и я не хочу платить кучу денег Accelereyes Jacket за использование простой функции Cuda, такой как cudaMemGetInfo ()или мои простые ядра Cuda.
Я нашел очень расстраивающее поведение, когда звонил Куде из Matlab.В Visual Studio 2008 я написал тривиальную DLL, которая использует стандартный интерфейс MEX для выполнения одного запроса Cuda: сколько свободной памяти на устройстве (листинг 1).
// cudaMemoryCheck.cpp : Defines the exported functions for the DLL application.
#include <mex.h>
#include <cuda.h>
#include <driver_types.h>
#include <cuda_runtime_api.h>
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
size_t free = 0, total = 0;
cudaError_t result = cudaMemGetInfo(&free, &total);
mexPrintf("free memory in bytes %u (%u MB), total memory in bytes %u (%u MB). ", free, free/1024/1024, total, total/1024/1024);
if( total > 0 )
mexPrintf("%2.2f%% free\n", (100.0*free)/total );
else
mexPrintf("\n");
// this is the critical line!
cudaDeviceReset();
}
Я компилирую проект Win32DLL (режим выпуска), куда я экспортирую функцию mexFunction с использованием файла DEF и переименую расширение файла DLL в .mexw32.
Когда я запускаю cudaMemoryCheck из Matlab, я обнаруживаю, что мой GPU будет пропускать память, если cudaDeviceReset ()закомментировано.Вот мой тривиальный код Matlab (листинг 2):
addpath('C:\Users\admin\Documents\Visual Studio 2008\Projects\cudaMemoryCheck\Release')
for i=1:20
clear mex
cudaMemoryCheck;
end
Запуск этой функции в Matlab, я вижу:
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
free memory in bytes 57393152 (54 MB), total memory in bytes 244776960 (233 MB). 23.45% free
Вывод из Matlab очень отличается, когда cudaDeviceReset () прокомментированout:
free memory in bytes 37019648 (35 MB), total memory in bytes 244776960 (233 MB). 15.12% free
free memory in bytes 25092096 (23 MB), total memory in bytes 244776960 (233 MB). 10.25% free
free memory in bytes 13549568 (12 MB), total memory in bytes 244776960 (233 MB). 5.54% free
free memory in bytes 12107776 (11 MB), total memory in bytes 244776960 (233 MB). 4.95% free
free memory in bytes 8568832 (8 MB), total memory in bytes 244776960 (233 MB). 3.50% free
free memory in bytes 9617408 (9 MB), total memory in bytes 244776960 (233 MB). 3.93% free
free memory in bytes 6078464 (5 MB), total memory in bytes 244776960 (233 MB). 2.48% free
free memory in bytes 8044544 (7 MB), total memory in bytes 244776960 (233 MB). 3.29% free
free memory in bytes 5816320 (5 MB), total memory in bytes 244776960 (233 MB). 2.38% free
free memory in bytes 7520256 (7 MB), total memory in bytes 244776960 (233 MB). 3.07% free
free memory in bytes 8830976 (8 MB), total memory in bytes 244776960 (233 MB). 3.61% free
free memory in bytes 5292032 (5 MB), total memory in bytes 244776960 (233 MB). 2.16% free
free memory in bytes 3407872 (3 MB), total memory in bytes 244776960 (233 MB). 1.39% free
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
free memory in bytes 0 (0 MB), total memory in bytes 0 (0 MB).
Итак, я пришел к выводу, что, хотя моя функция MEX не выделяет память на графическом процессоре, API Cuda Runtime создает новые CUcontexts при каждом запуске функции MEX и никогда не очищает их, покаЯ закрываю Matlab или использую cudaDeviceReset ().В конце концов, графическому процессору не хватает памяти, несмотря на то, что я ничего не выделял на нем!
Мне не нравится использование cudaDeviceReset ().API говорит: «Функция cudaDeviceReset () немедленно деинициализирует первичный контекст для текущего устройства вызывающего потока» и «Вызывающая сторона должна убедиться, что к этому устройству не обращаются никакие другие потоки узла из процесса, когда эта функцияназывается."Другими словами, использование cudaDeviceReset () может завершить другие вычисления GPU немедленно и без предупреждения.Я не нашел никакой документации, что использование cudaDeviceReset () часто является нормальным, поэтому я не хочу этого делать.Я приму любой ответ, который доказывает, что использование cudaDeviceReset () является нормальным и обязательным.
Информация о версии: NVIDIA GPU Computing Toolkit 4.0, Matlab 7.8.0 (R2009a, 32-разрядная версия), Windows 7 Enterprise SP1 (64-разрядная версия), Nvidia Quadro NVS 420 (последние версии драйверов Nvidia, 270.81).
Я также могу воспроизвести эту проблему в Windows XP (32-разрядная версия, SP3) с GeForce 8400 GS, тем же Matlab, Visual Studio и GPU Computing Toolkit.
Вывод deviceQuery.exe:
deviceQuery.exe Starting...
CUDA Device Query (Runtime API) version (CUDART static linking)
Found 2 CUDA Capable device(s)
Device 0: "Quadro NVS 420"
CUDA Driver Version / Runtime Version 4.0 / 4.0
CUDA Capability Major/Minor version number: 1.1
Total amount of global memory: 233 MBytes (244776960 bytes)
( 1) Multiprocessors x ( 8) CUDA Cores/MP: 8 CUDA Cores
GPU Clock Speed: 1.40 GHz
Memory Clock rate: 700.00 Mhz
Memory Bus Width: 64-bit
Max Texture Dimension Size (x,y,z) 1D=(8192), 2D=(65536,32768), 3D=(2048,2048,2048)
Max Layered Texture Size (dim) x layers 1D=(8192) x 512, 2D=(8192,8192) x 512
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 16384 bytes
Total number of registers available per block: 8192
Warp size: 32
Maximum number of threads per block: 512
Maximum sizes of each dimension of a block: 512 x 512 x 64
Maximum sizes of each dimension of a grid: 65535 x 65535 x 1
Maximum memory pitch: 2147483647 bytes
Texture alignment: 256 bytes
Concurrent copy and execution: No with 0 copy engine(s)
Run time limit on kernels: Yes
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: Yes
Concurrent kernel execution: No
Alignment requirement for Surfaces: Yes
Device has ECC support enabled: No
Device is using TCC driver mode: No
Device supports Unified Addressing (UVA): No
Device PCI Bus ID / PCI location ID: 3 / 0
Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
Device 1: "Quadro NVS 420"
CUDA Driver Version / Runtime Version 4.0 / 4.0
CUDA Capability Major/Minor version number: 1.1
Total amount of global memory: 234 MBytes (244908032 bytes)
( 1) Multiprocessors x ( 8) CUDA Cores/MP: 8 CUDA Cores
GPU Clock Speed: 1.40 GHz
Memory Clock rate: 700.00 Mhz
Memory Bus Width: 64-bit
Max Texture Dimension Size (x,y,z) 1D=(8192), 2D=(65536,32768), 3D=(2048,2048,2048)
Max Layered Texture Size (dim) x layers 1D=(8192) x 512, 2D=(8192,8192) x 512
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 16384 bytes
Total number of registers available per block: 8192
Warp size: 32
Maximum number of threads per block: 512
Maximum sizes of each dimension of a block: 512 x 512 x 64
Maximum sizes of each dimension of a grid: 65535 x 65535 x 1
Maximum memory pitch: 2147483647 bytes
Texture alignment: 256 bytes
Concurrent copy and execution: No with 0 copy engine(s)
Run time limit on kernels: Yes
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: Yes
Concurrent kernel execution: No
Alignment requirement for Surfaces: Yes
Device has ECC support enabled: No
Device is using TCC driver mode: No
Device supports Unified Addressing (UVA): No
Device PCI Bus ID / PCI location ID: 4 / 0
Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 4.0, CUDA Runtime Version = 4.0, NumDevs = 2, Device = Quadro NVS 420, Device = Quadro NVS 420