동시성과 병렬성

동시성과 병렬성 (threading & multiprocessing, parmap)

  • 사전지식
    • task (작업): 일의 단위라고 보면 된다. 1부터 100까지 더하는 것도 하나의 컴퓨팅 작업이며, 프로그램을 다운로드 하는 것도 하나의 작업이 될 수 있고, 프린트를 하는 것이나, 음악을 재생하는 것, 문서를 저장하는 것 등등이 모두 개별적인 서로 다른 작업이다.
    • sub-task (부분작업): 하나의 작업은 다시 작은 단위의 소작업들로 나뉠 수 있다. 이 때 소작업은 원래 작업과 하는 일 자체는 똑같다. 단지 전체 해야할 일에 일부를 할 뿐이다. 예를 들어, 1부터 100까지 더하는 task를 두 개의 sub-task 로 나눈다면, 1부터 50까지 더하고 51부터 100까지 더하는 것이다. 최종적으로 두 sub-task의 결과를 더하면 원래 task의 결과물이 나온다.
    • simultaneous (동시의): concurrent와 단어 자체의 의미는 같지만, 컴퓨터 분야에서는 서로의 의미가 조금 다르다. 이 때 simultaneous는 ‘그 순간에 정말로 동시에’ 라는 의미이다. at the exact time 이라고 종종 영어로 표현 되기도 한다. 이 단어가 중요한 것은 parallel 을 표현할 때 simultaneous 가 꼭 사용되기 때문이다.

우체국이 있습니다.
저는 소포를 보내려는 손님이죠.
손님들 100명이 우체국에 일렬로 줄을 서있고, 한명씩 처리하는것이 -> 싱글스레드 / 동기 처리입니다.
손님들 100명이 우체국의 100명의 직원에게 각각 처리하는 것이 -> 멀티쓰레드 / 동기 처리입니다.

여기까진 명쾌하죠.
그럼 손님들 100명이 우체국에서 번호표를 받아서 각각 자기 할일 하다가, 우체국에서 스마트폰으로 니 차례야 하고 알려주면 그 때 우체국에 순간이동(할 수 있다고 합시다)해서 소포를 보낼 수 있을 만큼 보내는것은??

네 이것은 싱글쓰레드 / 동기 처리입니다. 동기? 왜 동기 일까요? 사실 이것을 비동기로 봐도 되긴 합니다.
왜냐면 손님은 일단 기다리지 않고 (블럭되지 않고) 자기 할일을 할 수 있기 때문에, 비동기로 봐도 됩니다.
다만 하마님아~~~ 님 차례 됬다. 라고 알려주면 하마는 자기 소포를 보내게 되는데! 바로 이 순간은 동기의 순간입니다. 즉 내가 너무 많은 소포를 보내면 , 우체국은 다른 사람들에게 니 차례야 라고 말해줄 수 없는거에요. 병목이 생긴다는 의미입니다. (이게 Windows 에서 SELECT 이자, Java NIO 이며, Node.js 가 왜 비지니스로직이 길면 문제가 생기는지에 대한 대답입니다. 또한 node 나 자바,파이선의 selector 가 비동기 방식이라고 말하고 있는데 생각하기 나름입니다. 하이레벨에서의 구분이냐? 로우레벨에서의 구분이냐에 따라서 달리 볼수 있기 때문에~)

하지만
손님들 100명이 우체국 뒷마당에다가 소포를 던져두고, 이벤트 알림표를 받고 집에가서 자기 할일을 합니다.
그러다가 우체국에서 알림이 오겠죠. “니 소포 다 보냈어” , 다른 손님에게도 알림이 갑니다. “니 소포도 다 보냈어” 자~~~ 이렇게 되면 모두 병목에서 해방됩니다. 대신 우체국(OS) 가 더 많은 일을 하게 되겠죠.
이게 바로 진정한(?) 비동기 입니다. Windows 의 IOCP 입니다.

간단하게 차이를 정리하면
- 일을 할 수 있는지 알려주는 방식 (react)
- 일의 완료를 알려 주는 방식(proact)

입니다.

초기 각 언어의 라이브러리들은 반동기식(?)의 i/o를 지원해줬었고, 이제 몇몇 라이브러리들은 Proactor 패턴식의 비동기 I/O 입출력도 지원해 주기 시작했습니다. 파이썬도 EpollSelector / KqueueSelector / SelectSelector 등 지원함.

출처: 하마 블로그 https://hamait.tistory.com/833

동시성 (Concurrency)
  • 한 번에 여러 스레드를 다루는 것
  • 하나의 코어에서 여러 스레드가 번갈아가며 실행되는 성질
  • 동시에 실행되는 것처럼 보이지만 실제로는 시분할하여 번갈아 실행
  • 논리적 관점
병렬성(Parallelism)
  • 한번에 여러 스레드를 실행하는 것
  • 다중 코어에서 각 코어들이 동시에 실행되는 성질
  • 물리적 관점
결론

파이썬에서 병렬처리를 구현하는 방식은 두 가지로 멀티 쓰레드를 사용하거나 멀티 프로세스를 사용하는 것이다. 쓰레드는 가볍지만 GIL로 인해 계산 처리를 하는 작업은 한번에 하나의 쓰레드에서만 작동하여 cpu 작업이 적고 I/O 작업이 많은 병렬 처리 프로그램에서 효과를 볼 수 있다.

프로세스는 각자가 고유한 메모리 영역을 가지기 때문에 더 많은 메모리를 필요로 하지만, 각각 프로세스에서 병렬로 cpu 작업을 할 수 있고 이를 이용해 여러 머신에서 동작하는 분산 처리 프로그래밍도 구현할 수 있다.

출처
Share