레이블이 concurrency인 게시물을 표시합니다. 모든 게시물 표시
레이블이 concurrency인 게시물을 표시합니다. 모든 게시물 표시

concurrency 와 parallelism

concurrency(동시성) 와 parallelism(병렬성) 의 차이를 명확하게 알아보자.
golang.org 싸이트 대문에 Google I/O 2012 Go Concurrency 영상에서 두 차이를 설명하는 URL 을 따라가보면 잘 정리된 슬라이드를 볼 수 있다.
https://blog.golang.org/concurrency-is-not-parallelism

간단히 요약하자면
concurrency 는 다수의 작업을 동시에 처리하기 위한 (비록 한개의 프로세스를 사용하더라도) 구조를 일컫는 용어이고
parallelism 는 다수의 작업을 동시에 다수의 프로스세스에게 할당하여 수행하는 실행하는 방식
을 일컫는 용어이다.

위 슬라이드에서는 책을 소각할때의 예를 들고 있다.
다수의 책이 쌓여 있고 사용자(worker, 슬라이드에선 gopher로 표현)가 카트에 책을 담아 소각장으로 옮겨 소각 하는 과정에서

병렬성만을 생각하고 다수의 worker 를 두어 동시에 카트를 옮기면 빨리 작업이 완료될 것으로 보이지만 책이 쌓여 있는 장소와 소각장이 1개라는 점을 감안하면 책을 카트에 담을때와 소각장에서 소각을 할때는 병목현상으로 느려진다. 병렬성이라는 의미는 동시에 여러 프로세스를 사용한다는 의미일뿐 여기에 각 worker 의 작업 흐름에 대한 제어는 빠져있는 용어다.

동시성을 고려한다면 worker 하나는 책을 옮기는 동안 다른 worker 는 책을 카트에 담거나 책을 소각하는 등의 일을 한다. 이 과정에서 다수의 worker 를 사용할 가능성이 있으며 이는 곧 병렬성과 관련된다. 단순히 여러개의 worker 를 책 옮기는데에만 사용하는 병렬성의 기능을 잘 컨트롤하여 높은 성능을 발휘할 수 있게 한다.

동시성은 단순히 여러개의 프로세스를 사용한다는 의미의 병렬성이라는 말보다 한번더 효율적인 구조를 위해 작업 흐름을 제어하는 구조까지 생각하는 개념으로 풀이된다.

golang 은 기본적으로 concurrency 으로 구현되어 있고, concurrency 를 사용하는 과정에서 다수의 프로세스를 사용할 수 있기에 실행 방식 측면에서는 병렬성도 내포하고 있다.

참고 - 고루틴 동작 방식
https://tech.ssut.me/2017/08/20/goroutine-vs-threads/

golang concurrency(동시성) and parallelization(병렬성) 처리

// author : ysoftman
// encoding : utf-8
// title : 병렬화(parallelization) 테스트
// [desc]
// golang 의 go routine(고루틴) 이라고 하는 경량 쓰레드를 사용한다.
// 고루틴은 기본적으로 concurrency(동시성)하게 동작한다.
// 고루틴를 이용한 동시성 처리 예시 https://gobyexample.com/goroutines
// 만약 병렬처리(실제 다수의 cpu 를 사용해서 병렬 처리하는 경우)하려면
// 프로그램에서 사용할 수 있는 cpu 개수를 GOMAXPROCS 로 늘리면된다.
// 기본적으로 GOMAXPROCS 를 사용하지 않더라도 기본적으로
// 현재 머신의 cpu 개수로 설정되어 있다.
package main

import "runtime"
import "fmt"

func main() {
nCpu := runtime.NumCPU()
fmt.Println("Num Of CPUs =", nCpu)

// 프로그램에서 동시에 사용할 수 있는 cpu 개수 설정
nPreviousSetting := runtime.GOMAXPROCS(nCpu)
fmt.Println("Previous gomaxprocs =", nPreviousSetting)

// busy 작업을 하는 익명함수들을 고루틴으로 수행해 보자
// 4코어 cpu 의 경우 cpu 사용이 100%
// GOMAXPROCS 로 설정한 cpu 개수만큼 고루틴을 처리하게 된다.
// 프로그램 수행 후 cpu 사용율을 모니터링 해보자
go func() {
for {
}
}()

go func() {
for {
}
}()

go func() {
for {
}
}()

go func() {
for {
}
}()

fmt.Println("Num Of go routine =", runtime.NumGoroutine())

// cpu 100% 사용중이라면 키입력이 버벅거릴 수 있으니 주의
input := ""
fmt.Scanln(&input)
}