Golang
Goroutine: Concurrency vs Parallelism
Perbedaan antara konkurensi dan paralelisme pada goroutine di Go β kapan masing-masing terjadi dan faktor-faktor yang memengaruhinya.
Versi Bahasa Indonesia. Baca dalam Bahasa Inggris
Konkurensi (Concurrency): Goroutine memungkinkan banyak task berjalan secara independen. Mereka tidak harus berjalan pada waktu yang sama, tetapi memberikan kesan melakukannya dengan berbagi thread yang sama dan berpindah antar task.
Paralelisme (Parallelism): Goroutine dapat menjalankan banyak task secara bersamaan pada CPU multi-core jika sumber daya yang cukup dialokasikan.
Faktor Utama untuk Paralelisme
- Jumlah CPU Core:
- Runtime Go dapat mengeksekusi goroutine secara paralel pada banyak CPU core.
- Secara default, runtime menggunakan jumlah thread yang sama dengan jumlah CPU core yang tersedia.
- Pengaturan
GOMAXPROCS:- Fungsi
runtime.GOMAXPROCSmenentukan berapa banyak thread OS yang dapat digunakan runtime Go untuk eksekusi paralel. - Secara default,
GOMAXPROCSdiatur ke jumlah logical CPU.
- Fungsi
- Jenis Task:
- Task CPU-bound (misalnya kalkulasi matematika) dapat memanfaatkan paralelisme.
- Task I/O-bound (misalnya pembacaan file, request jaringan) lebih mengandalkan konkurensi dan tidak memerlukan banyak core untuk menjadi efisien.
Contoh: Parallel Goroutines
Contoh 1: Paralelisme dengan task CPU-bound
- Program ini mendemonstrasikan eksekusi paralel dengan memanfaatkan semua core yang tersedia.
- Empat goroutine melakukan tugas simulasi secara paralel.
- Jika mesin memiliki 4 core atau lebih, semua goroutine akan berjalan secara simultan.
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func compute(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Goroutine %d starting\n", id)
time.Sleep(2 * time.Second) // Simulasi task CPU-bound
fmt.Printf("Goroutine %d finished\n", id)
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) // Gunakan semua CPU core yang tersedia
fmt.Println("Running with", runtime.NumCPU(), "CPUs")
var wg sync.WaitGroup
for i := 1; i <= 4; i++ {
wg.Add(1)
go compute(i, &wg)
}
wg.Wait()
fmt.Println("All goroutines finished.")
}Contoh 2: Konkurensi tanpa Paralelisme
- Jika GOMAXPROCS diatur ke 1, semua goroutine akan dieksekusi secara sekuensial, meskipun ada banyak core.
- Dalam kasus ini, runtime hanya menggunakan satu thread, dan task tampak konkuren tetapi dieksekusi satu per satu.
runtime.GOMAXPROCS(1) // Paksa runtime untuk menggunakan hanya satu threadPerbedaan Utama
| Aspek | Konkurensi | Paralelisme |
|---|---|---|
| Eksekusi | Task berjalan secara independen. | Task berjalan pada waktu yang sama. |
| Utilisasi CPU | Bekerja baik bahkan pada CPU single-core. | Membutuhkan banyak CPU core. |
| Fokus | Mengelola banyak task secara efisien. | Mempercepat eksekusi task. |
| Contoh | Task I/O-bound seperti menangani request. | Task CPU-bound seperti kalkulasi matriks. |
Paralelisme dengan Goroutines: Catatan Praktis
- Tidak Selalu Dibutuhkan: Banyak aplikasi dunia nyata lebih bersifat I/O-bound (misalnya web server). Dalam kasus seperti itu, konkurensi lebih penting daripada paralelisme.
- Batas Paralelisme: Melampaui titik tertentu, menambah lebih banyak goroutine tidak akan meningkatkan performa karena faktor seperti contention, overhead, dan keterbatasan sumber daya.
- Profiling: Gunakan alat seperti
pprofatautraceuntuk mengukur dan mengoptimalkan performa program Go.
Edit on GitHub
Last updated on