🦉
Programming Notes
  • My Programming Notes
  • CKA Exam Preparation
    • Certified Kubernetes Administrator
    • Setup Minikube
    • Network Design Principles
    • Role-Based Access Control (RBAC)
    • Namespace
    • Resource Quota
    • Pod
    • Deployment
    • Deployment: Rollout
    • ConfigMap
    • Service
    • Service: kubectl expose
    • Pod: Resources Management
    • Pod & Container: Quality of Service Class
    • Pod & Container: Probes
    • Limit Range
    • Scaling: Manual
    • Scaling: Horizontal Pod Autoscaler
    • Persistent Volume & Claim
    • Secret
    • Ingress: Routing
    • Ingress: TLS
    • Ingress: Rate Limit
    • Ingress: Basic Auth
    • Ingress: CRD (Custom Resource Definition)
    • Job
    • CronJob
    • Mutli-Node Cluster
  • Golang
    • Generics
    • Context
    • Goroutines and Channels in Go
    • Goroutine: Concurrency vs Parallelism
    • Goroutine: Performance & Tradeoffs
    • JSON: omitzero
  • Rust
    • Arrays & Slices
    • Closures
    • Generics & Traits
    • Iterators
    • Run Code Simultaneously
    • String vs &str
    • Tests
    • Rustlings Exercises
      • Variables
      • Functions
      • If
      • Primitive Types
      • Vectors
      • Move Semantics
      • Structs
      • Enums and Matching Pattern
      • Strings
      • Modules
      • Hashmaps
      • Options
      • Error Handling
      • Generics
      • Traits
      • Lifetimes
      • Tests
      • Iterators
      • Smart Pointers
      • Threads
      • Macros
      • Quiz 1
      • Quiz 2
      • Quiz 3
  • Software Engineering
    • CAP Theorem
    • Circuit Breaker
    • Decoupling
    • GraphQL: Query Caching
    • HMAC Signature
    • Idempotency
    • Monolith VS Microservice
    • OWASP Top 10 2021
    • PCI DSS
    • PostgreSQL: Partitioning
    • PostgreSQL: Replication
    • Protobuf & gRPC
    • Redis: Streams
    • Resource Scaling
    • Signed URL
    • SOLID
    • Stack VS Heap
    • Stateful VS Stateless
  • Site Reliability Engineering
    • Chaos Engineering
    • Distributed Tracing
    • Kubernetes (k8s)
    • SLA, SLO, and SLI Metrics
    • Site Reliability Engineer
  • Others
    • FFMPEG Cheat sheet
Powered by GitBook
On this page
  • Key Factors for Parallelism
  • Example: Parallel Goroutines
  • Key Differences Between
  • Parallelism with Goroutines: Practical Notes
  1. Golang

Goroutine: Concurrency vs Parallelism

Concurrency: Goroutines allow multiple tasks to progress independently. They don't necessarily run at the same time, but they give the appearance of doing so by sharing the same thread and switching between tasks.

Parallelism: Goroutines can perform multiple tasks at the same time on multi-core CPUs if enough resources are allocated.

Key Factors for Parallelism

  • Number of CPU Cores:

    • Go's runtime can execute goroutines in parallel on multiple CPU cores.

    • By default, the runtime uses a number of threads equal to the number of available CPU cores.

  • GOMAXPROCS Setting:

    • The runtime.GOMAXPROCS function determines how many operating system threads the Go runtime can use for parallel execution.

    • By default, GOMAXPROCS is set to the number of logical CPUs.

  • Task Type:

    • CPU-bound tasks (e.g., mathematical calculations) can benefit from parallelism.

    • I/O-bound tasks (e.g., file reads, network requests) rely more on concurrency and don't require multiple cores to be efficient.

Example: Parallel Goroutines

Example 1: Parallelism with CPU-bound tasks

  • This program demonstrates parallel execution by utilizing all available cores.

  • Four goroutines perform a simulated task in parallel.

  • If the machine has 4 or more cores, all goroutines will execute simultaneously.

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) // Simulate a CPU-bound task
    fmt.Printf("Goroutine %d finished\n", id)
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU()) // Use all available CPU cores
    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.")
}

Example 2: Concurrency without Parallelism

  • If GOMAXPROCS is set to 1, all goroutines will execute sequentially, even if there are multiple cores.

  • In this case, the runtime uses only one thread, and tasks appear concurrent but are executed one at a time.

runtime.GOMAXPROCS(1) // Force the runtime to use only one thread

Key Differences Between

Aspect

Concurrency

Parallelism

Execution

Tasks progress independently.

Tasks execute at the same time.

CPU Utilization

Works well even on single-core CPUs.

Requires multiple CPU cores.

Focus

Managing multiple tasks efficiently.

Speeding up task execution.

Example

I/O-bound tasks like handling requests.

CPU-bound tasks like matrix calculations.

Parallelism with Goroutines: Practical Notes

  • Not Always Needed: Many real-world applications are more I/O-bound (e.g., web servers). In such cases, concurrency is more critical than parallelism.

  • Limits of Parallelism: Beyond a certain point, adding more goroutines won't improve performance due to factors like contention, overhead, and resource limits.

  • Profiling: Use tools like pprof or trace to measure and optimize performance in Go programs.

PreviousGoroutines and Channels in GoNextGoroutine: Performance & Tradeoffs

Last updated 4 months ago