Array MATLAB hidup di memori dalam blok berurutan — makin besar array, makin cepat ruangnya habis dan makin sering Out of memory muncul di momen terburuk. Kabar baiknya: kebutuhan memori bisa kita audit, pangkas, dan bagi cerdas dengan beberapa kebiasaan. Chapter ini menutup lima chapter pertama Section Optimasi dan Performa dengan audit whos, ukuran tipe data, salinan implicit, operasi in-place, dan strategi untuk dataset besar. Cakupan materinya:
- Audit memori per variabel dengan
whos - Tabel ukuran tipe:
double8 byte vssingle4 byte vsint81 byte - Copy-on-write: kapan MATLAB menyalin array secara diam-diam
- Operasi in-place dan pemrosesan per kolom untuk dataset besar
Audit Memori dengan whos #
Aturannya: whos melaporkan ukuran, kelas, dan jumlah byte tiap variabel di workspace. Mekanismenya: MATLAB menyimpan array sebagai blok data berurutan; whos menanyakan ukuran blok tersebut — hasilnya adalah numel dikali byte per elemen kelasnya. Empat variabel 1000×1000 berkelas berbeda memakan ruang yang sangat berbeda:
rng(42);
A = rand(1000, 1000); % double : 8 byte per elemen
B = single(A); % single : 4 byte per elemen
C = int8(A * 100); % int8 : 1 byte per elemen
D = A > 0.5; % logical: 1 byte per elemen
whosOutput yang Dihasilkan:
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
B 1000x1000 4000000 single
C 1000x1000 1000000 int8
D 1000x1000 1000000 logicalEmpat array dengan bentuk sama menempati 14 MB total — dari 8 juta byte untuk double hingga 1 juta byte untuk int8 dan logical. Tampilan whos sedikit berbeda antar versi MATLAB, tetapi kolomnya selalu sama: nama, ukuran, byte, kelas, dan atribut.
Ukuran Tipe Data #
Aturannya: pilih kelas terkecil yang masih memuat data dan presisinya. Mekanismenya: jumlah byte per elemen ditentukan kelasnya, sehingga konversi kelas langsung membagi-bagi kebutuhan memori. Kita bisa memverifikasi hitungannya secara manual — numel(A) * 8 — dan mencocokkannya dengan laporan whos:
fprintf('variabel kelas elemen byte/elem total byte (whos)\n');
fprintf('%-9s %-8s %8d %11d %16d\n', 'A', class(A), numel(A), 8, whos('A').bytes);
fprintf('%-9s %-8s %8d %11d %16d\n', 'B', class(B), numel(B), 4, whos('B').bytes);
fprintf('%-9s %-8s %8d %11d %16d %s\n', 'C', class(C), numel(C), 1, whos('C').bytes, ...
'(int8 membulatkan ke bilangan bulat)');
fprintf('%-9s %-8s %8d %11d %16d\n', 'D', class(D), numel(D), 1, whos('D').bytes);Output yang Dihasilkan:
variabel kelas elemen byte/elem total byte (whos)
A double 1000000 8 8000000
B single 1000000 4 4000000
C int8 1000000 1 1000000 (int8 membulatkan ke bilangan bulat)
D logical 1000000 1 1000000Tabel ringkas kelas yang paling sering kita jumpai:
| Kelas | Byte/elemen | Kapasitas / presisi |
|---|---|---|
double | 8 | ±1.8 × 10³⁰⁸, ~15–16 digit desimal |
single | 4 | ±3.4 × 10³⁸, ~7 digit desimal |
int8 / uint8 | 1 | −128…127 / 0…255 |
int16 / uint16 | 2 | ±32 767 / 0…65 535 |
int32 / uint32 | 4 | ±2.1 × 10⁹ / 0…4.3 × 10⁹ |
int64 / uint64 | 8 | ±9.2 × 10¹⁸ / 0…1.8 × 10¹⁹ |
logical | 1 | true/false |
char | 2 | satu karakter (UTF-16) |
Peringatannya: konversi ke kelas kecil memotong presisi dan jangkauan — int8(100.7) menghasilkan 101 (pembulatan), dan nilai di luar jangkauan terpotong ke batas. Untuk citra, mask, dan data sensor 8-bit, kelas kecil adalah kemenangan besar; untuk akumulasi numerik, double tetap default yang aman.
Salinan Implicit: Copy-on-Write #
Aturannya: assignment y = x tidak serta-merta menyalin data — MATLAB menunda penyalinan sampai salah satu variabel dimodifikasi. Mekanismenya: kedua nama mula-mula menunjuk blok data yang sama (copy-on-write); saat y(1) = 99 dieksekusi, barulah MATLAB menyalin blok tersebut agar x tidak ikut berubah. Dari sisi nilai, hasilnya identik dengan salinan penuh:
p = [10 20 30 40];
q = p; % q berbagi data dengan p, belum menyalin
q(1) = 99; % modifikasi pertama: data disalin untuk q
fprintf('p tetap utuh: %d %d %d %d\n', p);
fprintf('q sudah berubah: %d %d %d %d\n', q);Output yang Dihasilkan:
p tetap utuh: 10 20 30 40
q sudah berubah: 99 20 30 40Operasi In-Place #
Aturannya: bila hasil operasi menimpa variabel yang sama (x = x + 1), nyatakan dengan variabel yang sama di kedua sisi. Mekanismenya: MATLAB dapat memakai ulang buffer x untuk hasilnya bila aman — tidak ada nama lain yang menunjuk blok itu; bandingkan dengan y = x + 1 yang harus menyiapkan buffer kedua:
x = rand(1, 1000000);
fprintf('x (double, %d elemen): %d byte\n', numel(x), whos('x').bytes);
x = x + 1; % pola in-place: ruang x dapat dipakai ulang
fprintf('setelah x = x + 1 : %d byte (ukuran tidak bertambah)\n', whos('x').bytes);
y = x + 1; % bukan in-place: buffer baru untuk y
fprintf('setelah y = x + 1 : x = %d byte, y = %d byte\n', whos('x').bytes, whos('y').bytes);Output yang Dihasilkan:
x (double, 1000000 elemen): 8000000 byte
setelah x = x + 1 : 8000000 byte (ukuran tidak bertambah)
setelah y = x + 1 : x = 8000000 byte, y = 8000000 bytePola a(i) = a(i) + 1 di dalam loop adalah varian indexed-nya: elemen diperbarui di tempat tanpa salinan array penuh.
Praktik Dataset Besar #
Dataset yang tidak muat sekaligus diproses bertahap. Pertama, proses per kolom dan simpan ringkasan, lalu buang variabel besar dengan clear segera setelah tidak terpakai:
data = repmat(1:300, 4000, 1); % padanan dataset 4000x300
fprintf('data: %dx%d, %d byte\n', size(data, 1), size(data, 2), whos('data').bytes);
rataKolom = zeros(1, 300); % prealokasi hasil
for j = 1:300
rataKolom(j) = mean(data(:, j)); % satu kolom pada satu waktu
end
clear data % variabel besar dibuang segera
fprintf('rata-rata kolom 1-3: %.4f %.4f %.4f\n', rataKolom(1:3));
M = repmat(1:300, 4000, 1);
W = reshape(M, 300, 4000); % hanya metadata, data tetap dibagikan
fprintf('M: %d byte, W: %d byte (whos melaporkan ukuran logis)\n', ...
whos('M').bytes, whos('W').bytes);Output yang Dihasilkan:
data: 4000x300, 9600000 byte
rata-rata kolom 1-3: 1.0000 2.0000 3.0000
M: 9600000 byte, W: 9600000 byte (whos melaporkan ukuran logis)Mari kita bedah baris-baris kode di atas:
- Baris 6 (
rataKolom(j) = mean(data(:, j));): hanya satu kolom (32 KB) yang dipegang pada satu waktu — kebutuhan memori puncak turun drastis dibanding memproses matriks hasil berukuran penuh. - Baris 8 (
clear data;): 9,6 MB dikembalikan ke sistem sebelum tahap berikutnya berjalan. - Baris 12 (
reshape(M, 300, 4000)):reshapehanya menulis ulang metadata dimensi; blok data tidak disalin, sehinggaMdanWberbagi data yang sama.
Bila dataset benar-benar melampaui RAM, pecah proses menjadi beberapa tahap dan simpan hasil antara ke disk dengan save('tahap1.mat', 'hasil'), lalu load kembali di tahap berikutnya. Saat alokasi gagal, MATLAB melempar galat khas Out of memory. Type HELP MEMORY for your options. — sinyal untuk memecah data atau menurunkan kelas. Fungsi legacy pack (memampatkan workspace lewat disk) praktis tidak dibutuhkan pada MATLAB modern.
Ringkasan #
whos memberi kita angka pasti: double memakan 8 byte per elemen, single 4, int8 dan logical masing-masing 1 — verifikasi dengan numel × byte per elemen. Assignment murah berkat copy-on-write, namun modifikasi pertama memicu salinan penuh; x = x + 1 adalah bentuk in-place yang aman, dan reshape menata ulang dimensi tanpa menyalin. Untuk dataset besar: proses per kolom, clear segera, dan save hasil antara ke disk. Lima chapter pertama section ini melengkapi kotak alat performa dasar; lanjutan optimasi array dan function menempa alat itu lebih tajam.