Portal/Notes πŸ“
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.GOMAXPROCS menentukan berapa banyak thread OS yang dapat digunakan runtime Go untuk eksekusi paralel.
    • Secara default, GOMAXPROCS diatur ke jumlah logical CPU.
  • 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 thread

Perbedaan Utama

AspekKonkurensiParalelisme
EksekusiTask berjalan secara independen.Task berjalan pada waktu yang sama.
Utilisasi CPUBekerja baik bahkan pada CPU single-core.Membutuhkan banyak CPU core.
FokusMengelola banyak task secara efisien.Mempercepat eksekusi task.
ContohTask 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 pprof atau trace untuk mengukur dan mengoptimalkan performa program Go.

Edit on GitHub

Last updated on

Goroutine: Concurrency vs Parallelism | Faisal Affan