Dengan menetapkan matriks ke dalam memori yang dialokasikan jauh lebih besar, matlab entah bagaimana akan menduplikatnya sambil 'menyalinnya, dan jika matriks yang akan disalin cukup besar, akan ada memori yang berlebihan. Ini adalah kode contoh:
main_mat=zeros(500,500,2000);
n=500;
slice_matrix=zeros(500,500,n);
for k=1:4
parfor i=1:n
slice_matrix(:,:,i)=gather(gpuArray(rand(500,500)));
end
main_mat(:,:,1+(k-1)*n:1+(k-1)*n+n-1)=slice_matrix; %This is where the memory will likely overflow
end
Adakah cara untuk hanya 'menghancurkan' slice_matrix
ke atas main_mat
tanpa overhead? Terima kasih sebelumnya.
EDIT:
Overflow terjadi ketika main_mat
dialokasikan sebelumnya. Jika main_mat
diinisialisasi dengan main_mat=zeros(500,500,1);
(ukuran lebih kecil), overflow tidak akan terjadi, tetapi akan melambat karena alokasi tidak dilakukan sebelum matriks ditugaskan ke dalamnya. Ini akan secara signifikan mengurangi kinerja karena kisaran k
kenaikan
matlab
optimization
Gregor Isack
sumber
sumber
parfor
loop untuk tujuan optimasi . Selain itu,parfor
salin data Anda ke setiap pekerja yang terpisah, sehingga dengan asumsi 4 pekerja itu menggandakan data Anda empat kali dalam RAM.memory
fungsi ini? Manajer tugas? Kesalahan memori dari Matlab? Pada baris kode apa itu terjadi?main_mat(:,:,1+(k-1)*n:1+(k-1)*n+n-1)
adalah di mana masalah memori meluap terjadi. Itu diverifikasi ketika saya mengalokasikanmain_mat
sebelumnya, itu akan meluap, jika saya tidak, itu tidak akan. Matlab akan mengembalikan 'kehabisan memori kesalahan'.h=h+slice_matrix(end)
sebelummain_mat(:,:,1+(k-1)*n:1+(k-1)*n+n-1)=slice_matrix;
(dan menginisialisasi h dengan 0)? Saya menduga bahwa baris yang baru ditambahkan ini sudah akan menyebabkan masalah memori Anda.Jawaban:
Masalah utama adalah bahwa angka membutuhkan lebih banyak ruang daripada nol.
main_mat=zeros(500,500,2000);
membutuhkan sedikit RAM saatmain_mat = rand(500,500,2000);
mengambil banyak, tidak masalah jika Anda menggunakan GPU atau parfor (pada kenyataannya, parfor akan membuat Anda menggunakan lebih banyak RAM). Jadi ini bukan pembengkakan memori yang tidak wajar. Mengikuti tautan Daniel di bawah ini, tampaknya penugasan nol hanya menciptakan pointer ke memori, dan memori fisik hanya diisi ketika Anda menggunakan matriks untuk "angka". Ini dikelola oleh sistem operasi. Dan itu diharapkan untuk Windows, Mac dan Linux, baik Anda melakukannya dengan Matlab atau bahasa lain seperti C.sumber
zeros
seluruh memori virtual sebenarnya dialokasikan, tetapi tidak ada memori yang digunakan.whos
menunjukkan ukuran yang sama untuk kedua matriks, sedangkan os saya menunjukkan konsumsi memori yang berbeda. Saya menghapus komentar saya karena jawaban Anda pasti tidak salah.ones
alih - alihzeros
, ini memastikan memori sebenarnya dialokasikan pada saat memanggil fungsi masing-masing.main_mat
diberikan nilai bukan nol. Sebelumnya hanya memori virtual (ruang alamat) yang ditetapkan, ini sekarang ditugaskan untuk memori fisik.Menghapus
parfor
kemungkinan akan memperbaiki masalah Anda.parfor
tidak berguna disana. MATLABparfor
tidak menggunakan paralelisme memori bersama (yaitu tidak memulai utas baru) melainkan paralelisme memori terdistribusi (ini memulai proses baru). Ini dirancang untuk mendistribusikan pekerjaan melalui satu set atau node pekerja. Dan meskipun ia juga bekerja dalam satu node (atau satu komputer desktop) untuk mendistribusikan pekerjaan melalui beberapa core, itu bukan cara optimal untuk melakukan paralelisme dalam satu node.Ini berarti bahwa setiap proses yang dimulai
parfor
harus memiliki salinannya sendirislice_matrix
, yang merupakan penyebab besarnya jumlah memori yang digunakan oleh program Anda.Lihat "Putuskan Kapan Menggunakan
parfor
" dalam dokumentasi MATLAB untuk mempelajari lebih lanjut tentangparfor
dan kapan menggunakannya.sumber
parfor
adalah satu-satunya cara ? Pemrosesan bekerja paling baik ketika saya mendesainnya, karena semua yang ada di dalamnyaparfor
adalah CPU dan GPU intensif, sehingga secara signifikan meningkatkan kinerja.parfor
. Jika demikian, maka ya, itu kemungkinan berguna. - Mungkin jikaslice_matrix
bukangpuarray
itu tidak akan disalin dalam tugas.slice_matrix
bukangpuArray
, saya masih mendapatkan gejala overflow. Saya akan membiarkan pertanyaan ini terbuka, mari kita lihat apakah ada solusi alternatif. Terima kasih atas jawabannya!Saya berasumsi bahwa kode Anda hanya kode sampel dan itu
rand()
mewakili kebiasaan di MVE Anda. Jadi ada beberapa petunjuk dan trik untuk penggunaan memori di matlab.Ada cuplikan dari buku pegangan pelatihan The MathWorks:
Hal pertama yang harus dilakukan adalah memeriksa efisiensi (memori) kode Anda. Bahkan kode programer yang sangat baik dapat lebih dioptimalkan dengan (sedikit) kekuatan otak. Berikut adalah beberapa petunjuk mengenai efisiensi memori
sum(X,2)
,mean(X,2)
,std(X,[],2)
bsxfun
x = 2*x+3
alih-alihx = 2*x+3
Ketahuilah bahwa penggunaan memori yang optimal tidak sama dengan jika Anda ingin mengurangi waktu komputasi. Karena itu, Anda mungkin ingin mempertimbangkan mengurangi jumlah pekerja atau menahan diri untuk tidak menggunakan
parfor
-loop. (Karenaparfor
tidak dapat menggunakan memori bersama, tidak ada fitur copy-on-write dengan menggunakan Toolbox Paralel.Jika Anda ingin melihat lebih dekat pada memori Anda , apa yang tersedia dan yang dapat digunakan oleh Matlab, periksa
feature('memstats')
. Yang menarik bagi Anda adalah Memori Virtual ituNode sisi cepat : Matlab menyimpan matriks secara konsisten dalam memori. Anda perlu memiliki blok besar RAM gratis untuk matriks besar. Itu juga alasan mengapa Anda ingin mengalokasikan variabel, karena mengubahnya secara dinamis memaksa Matlab untuk menyalin seluruh matriks ke tempat yang lebih besar di RAM setiap kali melebihi tempat saat ini.
Jika Anda benar-benar memiliki masalah memori , Anda mungkin hanya ingin menggali seni tipe data - seperti yang diperlukan dalam bahasa tingkat yang lebih rendah. Misalnya Anda dapat memotong penggunaan memori Anda menjadi dua dengan menggunakan presisi tunggal langsung dari awal
main_mat=zeros(500,500,2000,'single');
- btw, ini juga berfungsi denganrand(...,'single')
dan lebih banyak fungsi asli - meskipun beberapa fungsi matlab yang lebih canggih membutuhkan input tipe ganda, yang Anda dapat disadap lagi.sumber
Jika saya mengerti benar masalah utama Anda adalah
parfor
tidak memungkinkan untuk berbagi memori. Pikirkan setiap pekerja parfor sebagai contoh matlab yang terpisah.Pada dasarnya hanya ada satu solusi untuk ini yang saya tahu (yang belum pernah saya coba), yaitu 'shared matrix' di Fileexchange: https://ch.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix
Lebih banyak solusi: seperti yang disarankan orang lain: menghapus parfor tentu saja merupakan salah satu solusi, mendapatkan lebih banyak ram, menggunakan array tinggi (yang menggunakan harddrives ketika ram berjalan penuh, baca di sini ), membagi operasi dalam potongan-potongan yang lebih kecil, last but not least, pertimbangkan alternatif selain Matlab.
sumber
Anda dapat menggunakan kode berikut. Anda sebenarnya tidak membutuhkan slice_matrix
sumber