Vektorisasi, preallocation, dan optimasi function memeras satu core habis-habisan — sementara mesin modern punya banyak core yang menganggur. Parallel Computing Toolbox menyalurkan pekerjaan MATLAB ke banyak worker lewat parfor, parfeval, dan spmd. Kabar jujurnya: paralel bukan tombol ajaib; overhead komunikasi dan bagian kode yang tetap serial sering membatalkan keuntungannya. Chapter ini membangun intuisinya dulu, baru sintaksnya. Cakupan materinya:
- Konsep task parallel vs data parallel, dan
parpoolsebagai kumpulan worker parfor: syarat kemandirian iterasi, reduction dan broadcast variable- Hukum Amdahl: speedup maksimum dibatasi fraksi serial (demo teruji)
parfevaldanspmdsekilas, plus padanan portabel tanpa toolbox
Task Parallel vs Data Parallel #
Dua pola paralel mendominasi praktik. Task parallel memecah pekerjaan yang berbeda ke beberapa worker: satu worker membaca file, satu lagi menghitung statistik. Data parallel menjalankan pekerjaan yang sama pada potongan data yang berbeda: setiap worker mengolah sepertiga elemen array. parfor adalah kendaraan data parallel — membagi rentang iterasi ke worker; parfeval kendaraan task parallel — mengantarkan satu tugas ke worker mana pun yang kosong.
| Aspek | Task parallel | Data parallel |
|---|---|---|
| Unit kerja | Tugas berbeda per worker | Tugas sama, data berbeda |
| Alat MATLAB | parfeval, spmd | parfor, gpuArray |
| Contoh | baca CSV + hitung + plot bersamaan | sqrt(x) pada 10 juta elemen |
| Cocok untuk | pipeline, simulasi parameter | loop independen berskala besar |
parpool dan parfor #
parpool memulai kumpulan worker — proses MATLAB terpisah yang siap menerima pekerjaan. Panggilan parpool tanpa argumen memakai default profile; parpool(4) secara eksplisit meminta empat worker. parfor lalu membagikan iterasi loop ke worker di pool tersebut:
parpool(4); % MATLAB-ONLY: mulai 4 worker
n = 1e6;
v = rand(n, 1);
total = 0; % reduction variable
hasil = zeros(1, n); % sliced variable
parfor k = 1:n
total = total + v(k); % tiap iterasi membaca v, menambah total
hasil(k) = v(k)^2; % tiap iterasi menulis potongan sendiri
endMari kita bedah baris-baris kode di atas:
- Baris 1 (
parpool(4);): membuat 4 proses worker; startup-nya sendiri memakan detik — biaya tetap yang harus ditutup keuntungan paralel. - Baris 5 (
total = 0;):totaladalah reduction variable — parfor mengenali polatotal = total + ...dan menggabungkan kontribusi tiap worker dengan aman. - Baris 6 (
hasil = zeros(1, n);):hasiladalah sliced variable — tiap iterasi menulishasil(k)miliknya sendiri, tidak saling menginjak. - Baris 8-11 (
parfor k = 1:n): rentang iterasi dibagi ke worker;vdibaca semua worker sebagai broadcast variable (baca saja, tidak diubah).
Syarat mutlak parfor: setiap iterasi harus independen — dokumentasi resmi menegaskan iterasi dieksekusi tanpa urutan terjamin, dan script tidak boleh dipanggil langsung di dalam parfor (function boleh). Iterasi yang memakai hasil iterasi sebelumnya bukan sekadar lambat — hasilnya salah karena belum tentu terhitung.
Mengapa Paralel Tidak Selalu Lebih Cepat #
Tiga biaya menunggu: startup parpool, pengiriman data ke worker (variabel di-broadcast lewat memori bersama), dan penggabungan hasil. Di atas semuanya berdiri hukum Amdahl: bila fraksi f dari waktu program tetap serial, speedup dengan p worker dibatasi 1 / (f + (1 - f) / p) — bagian serial tidak ikut menyusut. Tabel berikut dihitung langsung oleh contoh.m:
pekerja = [2 4 8 16];
fraksi = [0.05 0.10 0.25 0.50];
fprintf('Amdahl: speedup = 1 / (f + (1 - f) / p)\n');
fprintf(' f');
for p = pekerja
fprintf(' p=%-2d', p);
end
fprintf('\n');
for f = fraksi
fprintf('%6.2f', f);
for p = pekerja
speedup = 1 / (f + (1 - f) / p);
fprintf('%6.1f', speedup);
end
fprintf('\n');
end
fprintf('f = fraksi waktu yang tetap serial, p = jumlah worker\n\n');Output yang Dihasilkan:
Amdahl: speedup = 1 / (f + (1 - f) / p)
f p=2 p=4 p=8 p=16
0.05 1.9 3.5 5.9 9.1
0.10 1.8 3.1 4.7 6.4
0.25 1.6 2.3 2.9 3.4
0.50 1.3 1.6 1.8 1.9
f = fraksi waktu yang tetap serial, p = jumlah workerBacaan tabelnya: dengan 50% waktu serial, 16 worker hanya membeli speedup 1.9x. Meski program kita hanya 5% serial, 16 worker mentok di 9.1x — bukan 16x. Hukum Gustafson menyeimbangkan pesimisme ini: pada masalah yang membesar bersama jumlah worker, paralel tetap membeli kapasitas komputasi total yang jauh lebih besar; Amdahl menggambarkan satu program tetap, Gustafson menggambarkan masalah yang tumbuh.
parfeval dan spmd Sekilas #
parfeval menjadwalkan fungsi berjalan asinkron di worker dan langsung mengembalikan Future object — MATLAB tidak menunggu:
% MATLAB-ONLY
f = parfeval(@hitungStatistik, 1, data); % 1 output, jadwalkan sekarang
laporan = buatLaporan(); % ...kerjakan hal lain sambil menunggu
hasil = fetchOutputs(f); % ambil hasil saat dibutuhkanDokumentasi resmi menambahkan kabar ramah: tanpa pool dan tanpa toolbox, parfeval menjalankan fungsinya secara serial — kode tetap portabel untuk rekan tanpa Parallel Computing Toolbox. spmd (single program, multiple data) menjalankan blok yang sama di semua worker sekaligus, dengan spmdIndex sebagai identitas worker dan spmdSize sebagai jumlah worker; hasil yang keluar dari blok spmd menjadi Composite yang diakses per worker (s{2}). Gunakan spmd saat worker perlu saling berkomunikasi — domain distributed array di luar lingkup chapter ini.
Padanan Portable: Menguji Kemandirian Iterasi #
Tanpa toolbox pun, kita bisa membuktikan dua sifat yang menjadi syarat parfor. Pertama, iterasi independen menghasilkan jawaban yang sama dalam urutan apa pun (jumlah bilangan bulat tidak peduli urutan). Kedua, iterasi bergantung rusak bila urutannya diacak:
rng(42);
n = 12;
v = randi([1 50], 1, n);
totalUrut = 0;
for k = 1:n
totalUrut = totalUrut + v(k);
end
acak = randperm(n); % parfor tidak menjamin urutan eksekusi
totalAcak = 0;
for k = acak
totalAcak = totalAcak + v(k);
end
fprintf('iterasi independen: urut %d | acak %d | identik %d\n', ...
totalUrut, totalAcak, isequal(totalUrut, totalAcak));Jumlah bilangan bulat tidak peduli urutan — iterasi seperti ini aman untuk parfor. Loop kedua kebalikannya: saldo(k) membutuhkan saldo(k-1), sehingga mengacak urutan eksekusi menghasilkan jawaban salah:
saldo = zeros(1, n);
saldo(1) = v(1);
for k = 2:n
saldo(k) = saldo(k - 1) + v(k); % butuh hasil iterasi sebelumnya
end
salah = zeros(1, n);
for k = acak
if k == 1
salah(1) = v(1);
else
salah(k) = salah(k - 1) + v(k); % saldo(k-1) bisa masih 0
end
end
fprintf('iterasi bergantung: benar = %d | urutan acak identik = %d\n\n', ...
isequal(saldo, cumsum(v)), isequal(saldo, salah));Output yang Dihasilkan:
iterasi independen: urut 242 | acak 242 | identik 1
iterasi bergantung: benar = 1 | urutan acak identik = 0Loop kedua sengaja dijalankan dengan urutan acak: nilai saldo(k-1) bisa masih nol saat dibutuhkan, sehingga hasilnya melenceng dari cumsum(v) — inilah bentuk kegagalan yang sama bila iterasi bergantung dipaksakan ke parfor. Terakhir, contoh.m menutup dengan padanan manual parfor: membagi satu juta elemen ke empat potongan, tiap potongan dijumlahkan sendiri (reduction per bagian), lalu hasil bagian digabung — totalnya identik dengan sum(data).
Ringkasan #
Paralel dimulai dari parpool dan parfor, dengan dua kewajiban: iterasi independen (terbukti rusak pada demo urutan acak) dan pemahaman variabel — reduction, sliced, dan broadcast. Hukum Amdahl menjaga ekspektasi: 5% serial mentok di 9.1x untuk 16 worker; startup pool dan komunikasi memotong lagi. parfeval mengantarkan tugas asinkron, spmd menjalankan blok serentak dengan identitas spmdIndex. Ketika jumlah core masih kurang dan datanya jutaan elemen seragam, satu arah lagi terbuka: GPU — chapter berikutnya.