Paket parallel dan detectCores()
Luncurkan kluster fork atau soket dan distribusikan pekerjaan ke seluruh inti CPU.
Paket parallel dan detectCores() adalah pelajaran R Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar R Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus R Academy mencakup 4 pelajaran total.
Mengapa Komputasi Paralel?
Komputer modern memiliki beberapa inti CPU. Secara default, R berjalan pada satu inti sehingga inti lainnya menganggur. Paket parallel (bawaan R) memungkinkan Anda memanfaatkan semua inti untuk mempercepat komputasi berulang.
# Check how many cores your machine has
library(parallel)
total_cores <- detectCores()
logical_cores <- detectCores(logical = TRUE)
physical_cores <- detectCores(logical = FALSE)
cat('Total logical cores:', total_cores, '
')
cat('Physical cores:', physical_cores, '
')makeCluster dan stopCluster
makeCluster(n) membuat n proses pekerja. Selalu panggil stopCluster(cl) setelah selesai untuk membebaskan sumber daya. Konvensi yang umum adalah menggunakan detectCores() - 1 agar satu inti tetap tersedia untuk OS.
library(parallel)
# Spawn workers (leave 1 core for system)
n_cores <- detectCores() - 1
cl <- makeCluster(n_cores)
cat('Cluster created with', n_cores, 'workers\n')
# Always clean up!
stopCluster(cl)
cat('Cluster stopped.\n')clusterExport: Berbagi Variabel
Proses pekerja memiliki ruang memorinya sendiri dan tidak dapat melihat lingkungan global Anda. Gunakan clusterExport(cl, varlist) untuk menyalin objek bernama dari induk ke semua pekerja.
library(parallel)
cl <- makeCluster(2)
# Define a variable and a function in the master
base_value <- 100
add_base <- function(x) x + base_value
# Export them to workers
clusterExport(cl, varlist = c('base_value', 'add_base'))
# Now workers can use them
result <- parLapply(cl, 1:4, function(x) add_base(x))
cat(unlist(result), '\n') # 101 102 103 104
stopCluster(cl)clusterEvalQ: Menjalankan Kode Persiapan
clusterEvalQ(cl, expr) mengevaluasi suatu ekspresi pada setiap pekerja — berguna untuk memuat paket atau mengambil sumber berkas pembantu di semua node sebelum komputasi utama dimulai.
library(parallel)
cl <- makeCluster(2)
# Load a package on every worker
clusterEvalQ(cl, {
library(stats)
set.seed(42) # set seed per worker
})
# Each worker can now use stats functions
result <- parLapply(cl, 1:4, function(n) rnorm(n, mean = 0, sd = 1))
result[[1]] # one random normal value
stopCluster(cl)parLapply: lapply Paralel
parLapply(cl, X, FUN) adalah padanan paralel dari lapply(). Fungsi ini membagikan elemen X ke para pekerja dan mengumpulkan hasilnya sebagai daftar. Fungsi ini bekerja di semua platform (Windows, macOS, Linux).
library(parallel)
cl <- makeCluster(2)
# Simulate slow computation: sleep 0.1s per item
clusterEvalQ(cl, Sys.sleep)
slow_square <- function(x) {
Sys.sleep(0.05)
x^2
}
clusterExport(cl, 'slow_square')
system.time(
result <- parLapply(cl, 1:8, slow_square)
)
cat(unlist(result), '\n') # 1 4 9 16 25 36 49 64
stopCluster(cl)parSapply: Hasil yang Disederhanakan
parSapply(cl, X, FUN) adalah versi paralel dari sapply(). Fungsi ini otomatis menyederhanakan hasil menjadi vektor atau matriks jika memungkinkan, sehingga praktis ketika fungsi Anda mengembalikan skalar.
library(parallel)
cl <- makeCluster(2)
# parSapply returns a simplified vector
squares <- parSapply(cl, 1:10, function(x) x^2)
cat(squares, '\n') # 1 4 9 16 25 36 49 64 81 100
# Returns a matrix if FUN returns a vector of same length
stats_result <- parSapply(cl, 1:4, function(n) {
x <- rnorm(100)
c(mean = mean(x), sd = sd(x))
})
print(stats_result) # 2x4 matrix
stopCluster(cl)mclapply: Paralelisme Berbasis Fork
mclapply() menggunakan forking — fungsi ini menyalin proses R saat ini alih-alih membuat proses baru, sehingga lebih cepat dimulai dan memberi pekerja akses implisit ke lingkungan induk. Namun, fungsi ini hanya bekerja di Unix/macOS, bukan Windows.
library(parallel)
# mclapply: Unix/macOS only
# Workers inherit the parent environment automatically
base_value <- 42
if (.Platform$OS.type != 'windows') {
result <- mclapply(
1:8,
function(x) x * base_value, # base_value visible without export
mc.cores = 4
)
cat(unlist(result), '\n')
} else {
cat('mclapply not supported on Windows. Use parLapply instead.\n')
}Membandingkan Kinerja Sekuensial dan Paralel
Paralelisme memiliki overhead: startup klaster, serialisasi data, dan komunikasi antarproses semuanya membutuhkan waktu. Paralelisme hanya menguntungkan jika komputasi per elemen cukup mahal untuk mengimbangi overhead tersebut.
library(parallel)
cl <- makeCluster(2)
# Task: compute 100 iterations of matrix multiply
heavy_task <- function(n) {
m <- matrix(rnorm(200), nrow = 100)
sum(m %*% t(m))
}
clusterExport(cl, 'heavy_task')
seq_time <- system.time(lapply(1:20, heavy_task))[['elapsed']]
par_time <- system.time(parLapply(cl, 1:20, heavy_task))[['elapsed']]
cat('Sequential:', round(seq_time, 3), 's\n')
cat('Parallel: ', round(par_time, 3), 's\n')
cat('Speedup: ', round(seq_time / par_time, 2), 'x\n')
stopCluster(cl)Menetapkan RNG dalam Pemrosesan Paralel
Pembuatan bilangan acak secara paralel cukup rumit — setiap pekerja memerlukan aliran yang independen dan dapat direproduksi. Gunakan clusterSetRNGStream(cl, seed) dengan generator L'Ecuyer-CMRG untuk memperoleh keacakan paralel yang dapat direproduksi.
library(parallel)
cl <- makeCluster(2)
# Set reproducible RNG streams across workers
clusterSetRNGStream(cl, iseed = 123)
# Each worker uses its own independent random stream
results1 <- parSapply(cl, 1:6, function(i) rnorm(1))
# Reset and repeat — same results
clusterSetRNGStream(cl, iseed = 123)
results2 <- parSapply(cl, 1:6, function(i) rnorm(1))
cat('Run 1:', round(results1, 4), '\n')
cat('Run 2:', round(results2, 4), '\n')
cat('Identical:', identical(results1, results2), '\n')
stopCluster(cl)Penanganan Kesalahan dalam Klaster
Jika seorang pekerja menghasilkan kesalahan, parLapply() akan menghasilkan ulang kesalahan tersebut dalam proses induk. Bungkus pemanggilan dalam tryCatch() di dalam fungsi, atau gunakan tryCatch() di sekitar seluruh pemanggilan parLapply() untuk menangani kegagalan dengan baik.
library(parallel)
cl <- makeCluster(2)
# Wrap risky code inside the worker function
safe_log <- function(x) {
tryCatch(
log(x),
warning = function(w) NA_real_,
error = function(e) NA_real_
)
}
clusterExport(cl, 'safe_log')
# -1 produces NaN warning, 'a' produces an error
input <- list(4, 9, -1, 'a', 16)
result <- parLapply(cl, input, safe_log)
cat(unlist(result), '\n') # 1.386 2.197 NaN NA 2.773
stopCluster(cl)Pola Paralel Praktis
Berikut alur kerja paralel lengkap dan idiomatis: mendeteksi inti, membuat klaster, mengekspor dependensi, menjalankan komputasi, mengumpulkan hasil, dan selalu menghentikan klaster — bahkan jika terjadi kesalahan — menggunakan on.exit().
library(parallel)
run_parallel <- function(data, fn, n_workers = detectCores() - 1) {
cl <- makeCluster(n_workers)
on.exit(stopCluster(cl)) # guaranteed cleanup
clusterExport(cl, 'fn', envir = environment())
result <- parLapply(cl, data, fn)
result
}
# Example: bootstrap mean estimation
samples <- lapply(1:100, function(i) rnorm(50, mean = 5, sd = 2))
means <- run_parallel(samples, mean)
cat('Grand mean:', round(mean(unlist(means)), 3), '\n')
cat('95% CI: [',
round(quantile(unlist(means), 0.025), 3), ',',
round(quantile(unlist(means), 0.975), 3), ']\n')Pemeriksaan Singkat
Fungsi mana yang harus Anda gunakan untuk memastikan bahwa stopCluster(cl) dipanggil meskipun terjadi kesalahan dalam kode paralel Anda?
Ringkasan: Paket parallel
Hal-hal penting:
detectCores()melaporkan inti yang tersedia; gunakandetectCores() - 1untuk ukuran klastermakeCluster(n)/stopCluster(cl)mengelola siklus hidup pekerjaclusterExport()menyalin objek;clusterEvalQ()menjalankan kode persiapan pada pekerjaparLapply()/parSapply()adalah iterator paralel lintas platformmclapply()hanya tersedia di Unix, tetapi lebih cepat dimulai berkat forking- Gunakan
on.exit(stopCluster(cl))untuk pembersihan yang terjamin - Paralelisme hanya menguntungkan untuk tugas yang membutuhkan komputasi berat
# Minimal reproducible parallel pattern
library(parallel)
cl <- makeCluster(max(1, detectCores() - 1))
on.exit(stopCluster(cl))
clusterSetRNGStream(cl, iseed = 42)
result <- parSapply(cl, 1:8, function(x) x^2 + rnorm(1, 0, 0.1))
cat(round(result, 2), '\n')Pertanyaan yang Sering Diajukan
Apakah pelajaran “Paket parallel dan detectCores()” gratis?
Ya — teks lengkap “Paket parallel dan detectCores()” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus R Academy, upgrade ke CoddyKit PRO. Kursus R Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Paket parallel dan detectCores()”?
Luncurkan kluster fork atau soket dan distribusikan pekerjaan ke seluruh inti CPU. Kamu berlatih R Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai R Academy?
Tidak diperlukan pengalaman sebelumnya. R Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.
Berapa lama pelajaran “Paket parallel dan detectCores()” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran R Academy ini?
Ya. Setiap pelajaran R Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Paket parallel dan detectCores()
- Kerangka Kerja future
- furrr: Operasi purrr Paralel
- Men-debug dan Menyeimbangkan Beban Kode Paralel