안녕하세요.
애플의 modern concurrency 공부하기 이전에 애플이 thread를 다루는 역사가 궁금해서 앱 디벨로퍼 자료"Concurrency Programming Guide"를 번역 + 정리했습니다. 애플에 관한도 맞는 말이지만 컴퓨터 구조, 운영체제의 내용이 포괄적으로 담겨 있습니다.
사전에 알면 좋을 개념을 소개합니다.
프로그램 : hdd, ssd등 저장장치에 다운 받아진 실행 파일. 사용자의 터치, 마우스 클릭 등 실행되기 전의 상태인 실행파일.(아무것도 발생x, 생명 x)
프로세스: 사용자의 클릭, 터치, 스케줄러 등 (잠자고 있던) 프로그램을 메모리에 적재함으로 프로그램이 실행 중에 있는 상태.
대부분의 프로세스(실행중인 프로그램)은 background에서 실행되고 지속적인 프로세서 시간이 거의 필요하지 않는 작업을 수행합니다. 사용자의 관심과 함께 컴퓨터를 바쁘도록 하는 것은 foreground에 있는 프로세스 입니다.
1. CPU's single core
초기 컴퓨터는 CPU의 클럭 속도에 의해 단위 시간당 최대 작업량이 결정되었습니다.
"달랑 CPU의 속도 측정을 클럭속도에 의해 측정하다니"
multi core가 나온 이상 코어 수, CPU 캐시 및 전력 소비량등등 고려해야 할 요소가 많습니다.
기술은 발전했고 processor(cpu) design이 작아졌습니다. 열도 관리해야 합니다.(cpu위에 고기 굽는 영상을 본적 이있는데,,) cpu의 maximum 클럭 속도 또한 제한되기 시작했습니다.
칩 제조업체는 클럭 속도를 높이는 방법엔 한계가 임했고 다른 방법을 연구했습니다. 각각의 chip에 있는 processor의 core개수를 늘리는 방법입니다.(multi core의 출현) core수를 늘림으로 single chip는 칩의 크기를 늘리지 않아도 되고 cpu의 클럭속도를 높이지 않고도 더 많은 명령어를 연산 할 수 있게 됩니다.
"단일 칩에서 코어 개수를 늘릴 수 있는 기술은 확보했지만 core는 어떻게 활용할까?"
application이 많은 작업을 수행해야 할 때 cores의 일부분만 활용할 수 있다면 processing resource 낭비라 할 수 있습니다.(성능 좋은 컴퓨터를 굳이 산 이유가 없습니다.)
더 빠르고 많은 명령어를 실행할 수 있는 multiple cores의 혜택을 누릴려면 쉬고 있는 각각의 core를 활용해 task를 부여해야 합니다. 그러기 위해선 여러 개의 task를 관리하고 실행할 수 있는 software가 있어야 합니다. multitasking operating system like window, OS X, iOS etc...
카카오톡, 유튜브, 스트리밍 앱, 크롬 등 많은 프로그램이 실행될 수 있습니다. 그리고 프로세스는 관리되야 합니다. 여러 코어에 프로세스를 스케줄링함으로 많은 프로세스가 실행중인 상태에 있는 것이 가능합니다.
여러 프로그램을 실행한다면 프로그램들이 동시에 실행되고 있는 것처럼 보입니다. 대부분은 system demon 또는 background에 있습니다. 이렇게 때문에 foreground에 있는 사용자가 지금 바라보고 있는 클라이언트 속 프로세스에 core를 더 활용함으로 효과적으로 사용할 수 있게 됩니다.
2. What about concurrency design in Swift?
이전 포스트에서 concurrency와 thread에 대해 간략하게 다뤘습니다.
간략하게 요약하자면 "concurrency는 context switch를 통해 task를 바꿔가며 실행한다.", "concurrency를 사용하기 위해선 thread를 한 개 또는 여러 개 사용해야 한다." 입니다.
Concurrency는 여러 개의 task가 동시에 실행되는 것입니다. cpu가 single -> multi cores가 됬다는 말은 곧 일을 여러개 할 수 있다는 의미입니다.
초기 Swift는?? multi core를 multi thread(NSThread)를 생성함으로 concurrency를 구현했습니다. 하지만 core수는 증가했고 thread를 사용한 것이 문제가 됬습니다. core는 늘어났지만 thread가 임의의 core수 만큼 잘 확장되지 않는다는 점입니다. 효율적으로, 지금 바로 사용 가능한 cores를 파악해야 효율적으로 task에게 할당할 수 있기 때문입니다. application은 스스로 core 개수를 계산하기 어렵습니다. 또한 많은 thread가 생성된다면 실행에 있어 서로 간섭을 하지 않도록 구현되야 합니다.
NSThread로 동시성을 구현하게 된다면 thread를 담당하는 thread pool을 구현해야 합니다. 임시적으로 들어온 task들을 queue에 삽입하고 각각의 task를 담당하는 thread를 생성하고 task를 부여하고 삭제하는 thread pool을 지속적으로 관리해야 합니다. 기존의 프로그램은 순차적인 실행을 합니다. 만약 concurrency를 구현하고 같이 활용하게 된다면 multi threading의 복잡도는 증가하게 됩 니다. 성능의 개선도 보장할지는 의문입니다.
thread는 low-level tool입니다. 수동으로 관리하기 어렵습니다. 최적으로 지정한 thread 개수가 시스템 과부하가 걸리게 되어 더 많은 thread를 필요하게 된다면 등 dynamically하게 바뀔 수 있습니다. 이런 경우 마다 solution이 처리되어 있어야 합니다.
Application은 multi core를 사용할 수 있는 방법이 필요했습니다. 어떤 한 프로세스가 과부하가 걸리거나, 많은 task를 담당하게 될 때 system 조건을 수용할 수 있도록 동적으로 확장해야 합니다.
OS X, iOS는 Asynchronous 접근법을 적용했습니다.(전통적으로 찾을 수 있는 thread-base system 말고 asynchronous). Thread를 바로 생성하지 않고 application은 그저 필요한 특정 task를 정의하고 submit하면 이는 system에서 관리합니다. (그러나 애플리케이션에 따라 커스텀 thread를 구현해야 할 경우 가 있습니다.)
애플의 operating system은 multi cores를 효율적으로 다룰 수 있는 API를 제공합니다.
- NSThread
- NSOperationQueue
- DispatchQueue
- Async/Await ( modern concurrency )
포스트 내용 중 틀린 부분이 있다면 댓글로 알려주신다면 감사합니다.
참고 자료
https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008091-CH1-SW1