これはGPU側にキャッシュが残っているためです。
「メモリのキャッシュにより、この値は NVIDIA® System Management Interface で報告される値と異なる場合があります。」
とあります。
gpuArrayを作成後とクリア後にGPUのメモリ使用量を表示するようにコードを変えてみました。
MATLABからgpuDeviceコマンドで選択されているGPU情報を取得し、gd.TotalMemory-gd.AvailableMemoryでMATLABから見たGPUのメモリ使用量が見えます。
また、nvidia-smiコマンドでGPUのキャッシュを含むメモリ使用量が確認できます。下記の「--id=0」のオプションはGPUが複数ささっていて、1台目のGPUデバイスの情報を表示させるためのオプションです。
すると、p0をクリアした直後、MATLABのgpuDeviceではメモリ使用量がすぐに減っていますが、nvidia-smiコマンドだと使用量がすぐには変わっていないことがわかりました。GPU側にキャッシュが残っているためです。
WindowsのタスクマネージャーからGPUのメモリ使用量を見るとnvidia-smiの値に近いことが分かりました。
キャッシュが削除されるタイミングはGPU側で制御されます。
nvidia-smi -caaコマンドや、MATLABからもgpuDeviceのreset コマンドがありますが、GPUのメモリが全て消去されてしまうので、特定のキャッシュだけ削除するというのは無さそうです。
ただ、キャッシュはいずれ削除されますし、現状のMATLABからclear p1などでGPU配列を消去してから新たにGPU配列を定義する方法で良いと思います。
clc;clear
X = 1200; Y = 200; Z = 200; % 写真 上
% X = 1800; Y = 300; Z = 200; % 写真 下
p0=gpuArray.rand(X,Y,Z);
gd = gpuDevice;
disp('p0');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
p1=gpuArray.rand(X,Y,Z);
disp('p1');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
p2=gpuArray.rand(X,Y,Z);
disp('p2');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
p3=gpuArray.rand(X,Y,Z);
disp('p3');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
p4=gpuArray.rand(X,Y,Z);
disp('p4');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
clear p0
disp('cleared p0');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
clear p1
disp('cleared p1');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
clear p2
disp('cleared p2');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
clear p3
disp('cleared p3');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0
pause(3)
clear p4
disp('cleared p4');sprintf('%d MiB / %d MiB', round((gd.TotalMemory-gd.AvailableMemory)/1024/1024), round(gd.TotalMemory/1024/1024))
!nvidia-smi --id=0