2502 words
13 minutes
260118_Parallels_VS_Concurrency

link#


Rc & Arc사용법 표로 이해|🔝|#

그림으로 Concurrency VS Parallelism 설명 (54초부터)|🔝|#

시스템 프로그래밍 개요|🔝|#

프로세서 상태 다이어 그램|🔝|#

Future(Rust trait.Future)|🔝|#

1.3.1 플린의 분류법|🔝|#

Single core
processor
Vector
processor
ex) GPU
SISD
Single instruction steam
Single data stream
SIMD
Single instruction stream
Multiple data stream
-MISD
Multiple instruction stream
Single data stream
MIMD
Multiple instruction stream
Multiple data stream
-
Not covered
(실제 구현 사례 없음?)
--Multi-core processor
ex) CPU
  • [그림 1-12] 플린의 병렬 처리 하드웨어 분류(CUDA 기반 GPU 병렬 처리 프로그래밍p.17)

  • 2.2.7. SIMD의 한계

  • (210819)22. 컴퓨터구조 - 파이프라인과 병렬처리 by devraphy

  • Michael J. Flynn이 1966년에 제안한 컴퓨터 아키텍처 구분법(Flynn’s taxonomy) 은 컴퓨팅 하들웨어를 두 가지 기준을 통해 네 종류로 분류.

    • ① 데이터에 대해 한 번에 수행하는 명령어(instruction) 개수와
    • ② 명령어가(또는 명령어들이) 수행되는 데이터(data) 개수다.
  • 단일명령-단일데이터(Single Instruction-Single Data, SISD)는 하나의 명령어를 하나의 데이터에 대해 수행하는 가장 간단한 구조로, 단일 코어 CPU와 같이 하나의 코어를 가지는 직렬 처리 연산 장치가 이에 속한다.

  • 복수명령-단일데이터(Multiple Instruction-Single Data, MISD)는 여러 개의 명령어를 하나의 데이터에 동시에 수행하는 구조를 말함.

    • MISD 구조는 개념적으로만 기술되는, 아직 실현되지 않은 컴퓨터 아키텍처.
  • MIMD(ex. CPU)

    • 다수의 SISD가 하나의 칩 안에 들어 있는 구조.
      • 독립됐다는 뜻은 각 프로세서가 자신만의 제어 장치(control unit)와 문맥(context)를 가진다는 의미
    • MIMD는 여러 개의 연산 유닛을 가지므로, 여러 스레드가 병렬로 동시에 작업을 수행하게 된다. 쉽게 이야기하자면 각 연산 유닛이 서로 다른 일을 한다고 생각하면 된다. MIMD 기반 병렬 처리는 각 스레드에 독립된 작업(task) 들을 분배하는 경우가 많으며, 이러한 병렬 처리 기법을 태스크 수준 병렬화(task-level parallelism) 라고 부른다.
  • SIMD

    • 병렬 처리 하드웨어의 또 다른 형태는 하나의 동일한 명령어를 여러 개의 데이터에 대해 수행하는 SIMD구조.
      • SIMD 구조의 병렬 처리 하드웨어는 데이터 배열에 연산이 적용된다는 의미에서 벡터 프로세서(vector processor) 또는 배열 프로세서(array processor)라고도 한다.
      • ex) GPU

I/O Multiplexing(select, poll, epoll, kqueue)|🔝|#

(용어 이해)유휴 시간, 遊休時間, idle time, off-time|🔝|#

ps로 현재 프로세스가 돌아가는거 확인하기|🔝|#

$ ps
  PID TTY           TIME CMD
 1530 ttys000    0:00.05 -fish

thread 확인은 top|🔝|#

$ top

Go개발자가 정리한 (Goroutines)|🔝|#

MS-Dos는 싱글 쓰레드 OS|🔝|#

parallelism Rust 코드로 이해하기|🔝|#

  • (sleep 실패한 이유 알아보기)쓰레드 아이디를 보며 parallelism이해하기
fn get_proc() {
    println!("{:?}", std::thread::current().id());
    println!("{}", std::process::id());
    std::thread::sleep(std::time::Duration::from_secs(1));
}

fn main() {
    let thread1 = std::thread::spawn(|| {
        get_proc();
    });
    let thread2 = std::thread::spawn(|| {
        get_proc();
    });
    get_proc();
    thread1.join().unwrap();
    thread2.join().unwrap();
}
  • (sleep성공한 코드)
fn get_proc() {
    println!("{:?}", std::thread::current().id());
    println!("{}", std::process::id());
}

fn main() {
    let thread1 = std::thread::spawn(|| {
        get_proc();
    });
    std::thread::sleep(std::time::Duration::from_secs(1));

    let thread2 = std::thread::spawn(|| {
        get_proc();
    });
    std::thread::sleep(std::time::Duration::from_secs(1));

    get_proc();
    thread1.join().unwrap();
    thread2.join().unwrap();
}
  • parallelism설명 예시
use std::thread;
use std::time::Duration;


fn fibonacci_sequence(n: usize) -> Vec<u32> {
    let mut sequence = vec![0, 1];
    if n > 1 {
        for _ in 2..(n + 1) {
            let next = sequence[sequence.len() - 1] + sequence[sequence.len() - 2];
            sequence.push(next);
        }
    }
    sequence
}

fn main() {
    let num_threads = 4;
    let mut handles = Vec::new();

    for i in 0..num_threads {
        let handle = thread::spawn(move || {
            println!("Thread {} started.", i);
            let fibonacci = fibonacci_sequence(i * 10);
            println!(
                "Thread {} computed Fibonacci sequence of length {}",
                i,
                fibonacci.len()
            );
            println!("Thread {}: Fibonacci sequence: {:?}", i, fibonacci);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

Below is a clear, systems-level explanation of Concurrency vs Parallelism, with:|🔝|#

  • ✅ A comparison table
  • ✅ Timeline diagrams (visual intuition)
  • ✅ Rust code examples for each
  • ✅ When to use which
    • I’ll keep this precise and Rust-centric.

1️⃣ Definitions (short and accurate)|🔝|#

  • 🔁 Concurrency

Structuring a program to handle multiple tasks in overlapping time, even if only one runs at a time.

  • About dealing with many things

  • Can run on one thread

  • Uses interleaving

  • ⚡ Parallelism

Executing multiple tasks at the same time on multiple CPU cores.

  • About doing many things at once
  • Requires multiple threads / cores
  • Uses simultaneous execution

  • 🔁 동시성

한 번에 하나만 실행되더라도 여러 작업을 겹치는 시간에 처리할 수 있도록 프로그램을 구성합니다.

  • 많은 일을 처리하는 것에 대하여

  • 하나의 스레드에서 실행 가능

  • 인터리빙 사용

  • ⚡ 병렬 처리

여러 CPU 코어에서 여러 작업을 동시에 실행하기.

  • 한 번에 여러 가지 일을 하는 것에 대해
  • 여러 스레드/코어가 필요합니다
  • 동시 실행 사용

2️⃣ Core differences (table)|🔝|#

AspectConcurrencyParallelism
GoalResponsiveness, structurePerformance, speed
Runs at same time?❌ Not necessarily✅ Yes
CPU cores1 or more2+ required
ThreadsOptionalRequired
FocusTask coordinationWork distribution
Typical toolsasync/await, mutex, channelsthreads, rayon, atomics
ExampleAsync serverParallel computation

3️⃣ Timeline visualization (key intuition)|🔝|#

🧵 Concurrency on one core#

Time →
Task A: ███░░░░░██░░░
Task B: ░░░███░░░░███
CPU   : █████████████
  • Only one task runs at a time
  • Tasks take turns
  • Appears simultaneous, but isn’t

🧵🧵 Parallelism on multiple cores#

Time →
Core 1: █████████
Core 2: █████████
Task A: █████
Task B: █████
  • asks actually run at the same time
  • True parallel execution

🔁 Concurrency + ⚡ Parallelism (real systems)#

Core 1: Task A ─ Task C
Core 2: Task B ─ Task D
  • Most real systems use both.

4️⃣ Concurrency example (Rust, single thread)|🔝|#

  • Example: Cooperative concurrency with async
use std::time::Duration;

async fn task_a() {
    for i in 0..3 {
        println!("A {i}");
        tokio::time::sleep(Duration::from_millis(100)).await;
    }
}

async fn task_b() {
    for i in 0..3 {
        println!("B {i}");
        tokio::time::sleep(Duration::from_millis(100)).await;
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    tokio::join!(task_a(), task_b());
}
  • What’s happening
    • One OS thread
    • Tasks yield at .await
    • Scheduler interleaves execution
    • This is concurrency, not parallelism

5️⃣ Parallelism example (Rust threads)|🔝|#


use std::thread;

fn main() {
    let t1 = thread::spawn(|| {
        for i in 0..5 {
            println!("Thread A {i}");
        }
    });

    let t2 = thread::spawn(|| {
        for i in 0..5 {
            println!("Thread B {i}");
        }
    });

    t1.join().unwrap();
    t2.join().unwrap();
}
  • What’s happening
    • Two OS threads
    • Can run on different CPU cores
    • True parallel execution

6️⃣ Parallel data processing (idiomatic Rust)|🔝|#

use rayon::prelude::*;

fn main() {
    let v: Vec<i64> = (1..=1_000_000).collect();

    let sum: i64 = v.par_iter().map(|x| *x * 2).sum();

    println!("{sum}");
}
  • Work is split across threads
  • Data-parallel
  • This is pure parallelism

7️⃣ Concurrency without parallelism (Mutex example)|🔝|#

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));

    let handles: Vec<_> = (0..3).map(|_| {
        let counter = Arc::clone(&counter);
        thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        })
    }).collect();

    for h in handles {
        h.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
  • Multiple threads
  • Only one enters the critical section at a time
  • Concurrency without effective parallelism inside the lock

8️⃣ When to use which|🔝|#

  • Use Concurrency when:

    • Many I/O tasks
    • Waiting on network / disk
    • UI responsiveness
    • Async servers
  • Use Parallelism when:

    • CPU-bound work
    • Large computations
    • Data processing
    • Image/video processing

9️⃣ Common misconception (important)|🔝|#

  • 일반적인 오해 (중요

  • ❌ Concurrency ≠ Parallelism

  • You can have:

    • Concurrency without parallelism (async on one thread)
    • Parallelism without much concurrency (batch computation)
    • Both together (most real systems)
  • 가질 수 있습니다:

    • 병렬 처리가 없는 동시성(하나의 스레드에서 비동기화)
    • 동시성이 크지 않은 병렬 처리(배치 계산)
    • 둘 다 함께 (대부분의 실제 시스템)

🔟 One-sentence summary|🔝|#

  • Concurrency is about structuring programs to manage multiple tasks, while parallelism is about executing multiple tasks at the same time — Rust gives you first-class tools for both, and they often work best together.

  • 🔟 한 문장 요약

    • 동시성은 여러 작업을 관리하기 위해 프로그램을 구조화하는 것이고, 병렬성은 여러 작업을 동시에 실행하는 것입니다. Rust는 두 작업 모두에 대해 최고 수준의 도구를 제공하며, 종종 함께 작동합니다.

관련된 다른 블로그 글#

260118_Parallels_VS_Concurrency
https://younghakim7.github.io/blog/posts/260118_parallels_vs_concurrency/
Author
YoungHa
Published at
2026-01-18