### Concurrency Programming #### 동시성(Concurrency) 프로그래밍, 병렬(Parallelism) 프로그래밍은 어떻게 다르며, 우리가 주로 접할 iOS 환경에서는 무엇을 더 고려해봐야 할까? #### 동시성 프로그래밍 - 멀티 스레드, 논리적으로 동시에 실행 - 하나의 CPU가 여러 작업을 동시에 처리하는 거처럼 보이는 것 - 실질적으론 하나의 작업만을 하는 것이지만, 논리적으로 여러 작업을 동시에 처리(스케줄링을 통해 빠른 컨텍스트 스위칭을 하며 진행) - 컨텍스트 스위칭이 스레드 단위로 일어나기 때문에 코어 단위보다 비용이 저렴 - 하나의 CPU 안에 **여러 개의 논리적인 스레드**를 사용하여 동시에 **여러 작업**을 처리하는 것 ![](https://hackmd.io/_uploads/H1ULu1eK2.gif) #### 병렬 프로그래밍 - 멀티 프로세서, 물리적으로 동시에 실행 - 여러 개의 코어가 하나의 일을 분담하여 동시에 처리 - 물리적인 코어가 여러개 일 때 가능(싱글 코어X) -> 물리적으로 동시에 프로세스를 처리한다 - 많은 연산이 필요한 그래픽 처리, 머신러닝에서 사용 - 컨텍스트 스위칭이 프로세서 단위에서(코어) 일어나기 때문에 비용이 높음 -> iOS 환경에서는 동시성 프로그래밍을 고려해야 하는 경우가 많습니다. iOS 애플리케이션은 주로 비동기적인 작업을 다루는데, 네트워크 요청, 데이터 다운로드, 사용자 입력 처리 등이 비동기적으로 처리되어야 합니다. iOS에서는 Grand Central Dispatch(GCD)와 Operation Queue를 통해 동시성을 구현할 수 있습니다. ![](https://hackmd.io/_uploads/rkAHSJgY2.png) #### 동시성 프로그래밍, 병렬 프로그래밍, 동기(synchronous)와 비동기(asynchronous)의 개념은 어떤 상관관계를 가질까? #### 동기(Synchronous) - 작업이 끝날 때까지 기다리는 것. 코드 실행이 완전히 끝나야 다음 코드로 넘어감 - **실행 종료 시점을 알 수 있기** 때문에, 작업이 종료된 후 할 일을 정할 수 있다 #### 비동기(Asynchronous) - 작업이 끝나지 않아도 다음 코드 블록을 바로 실행시키는 것. - **실행 종료 시점을 알 수 없다** ![](https://hackmd.io/_uploads/rys5VJgK2.png) #### 애플이 동시성 프로그래밍 또는 병렬 프로그래밍을 지원하기 위해 사용하는 기술엔 무엇무엇이 있을까? - GCD - Dispatch Queue는 기본적으로 FIFO 방식으로 먼저 들어온 작업을 먼저 처리한다 (qos 파라미터를 통해 우선순위를 지정해 우선순위가 높은 작업을 먼저 처리하도록 지정 가능) - Dispatch.main.async를 사용하면 매번 새 스레드가 생성되기 때문에 스레드의 갯수가 커지면 context switch 비용이 올라갈 수 있다 - Operation Queues - #### 프로그래밍에서 Thread는 무엇이고 iOS 환경에서 이를 다루기 위한 방법에는 무엇무엇이 있으며 그 차이는 무엇일까? #### 스레드 - 하드웨어 스레드 → **논리적인 코어** → 1코어 2스레드 : 하나의 코어로 2가지 작업을 동시에 수행할 수 있도록 함(하이퍼스레딩 기술) → 2코어인 거 같은 느낌! - **소프트웨어 스레드** → **논리적인 스레드** : 프로세스 내부에서 작업 단위가 되는 가상의 스레드 → 가상의 스레드이기 때문에 물리적 스레드와 상관 없이 많이 생성 가능 → 소프트웨어에서 멀티 스레딩 = 동시성 프로그램 #### Serial Queue / Concurrent Queue - Serial Queue - 단일 스레드 순차적 작업 처리(동기처리용) - DispatchQueue의 attribute **default 값**은 .serial ```swift // Serial Queue DispatchQueue(label: "Serial") DispatchQueue.main // main은 전역적으로 사용되는 Serial DispatchQueue 입니다. ``` - Concurrent Queue - 다중 스래드 동시 작업 처리(비동기처리용) ```swift // Concurrent Queue DispatchQueue(label: "Concurrent", attributes: .concurrent) DispatchQueue.global() ``` ### Process, Processor #### Windows 운영체제는 32bit 버전, 64bit 버전, ARM 버전 등 다양한 버전이 존재합니다. 이 버전은 어떤 것을 의미하며 왜 이렇게 다양한 버전이 존재해야 할까요? → 32bit, 64bit : 명령어의 길이의 차이이고 64bit가 더 표현할 수 있는 부분이 더 넓어진다. → 64비트 운영체제는 더 큰 주소 공간을 처리할 수 있으며, 이는 더 많은 시스템 메모리를 사용할 수 있음을 의미합니다. 64비트 운영체제는 더욱 뛰어난 성능과 안정성을 제공하며, 대부분의 최신 소프트웨어와 하드웨어와의 호환성을 보장합니다. → ARM: ARM은 모바일 기기와 같은 저전력 장치에 사용되는 프로세서 아키텍처입니다. 모바일 운영체제와의 호환성 및 모바일 기기에 적합한 기능을 제공합니다. → 하드웨어가 발전함에 따라 소화할 수 있는 명령어의 길이가 넓어진다. 더 큰 명령어를 빨리 처리할 수 있다 → 각 버전이 존재하는 이유는 다양한 하드웨어 아키텍처와 용도에 따라 최적화된 운영체제를 제공하기 위함 #### 내 매킨토시의 프로세서는 무엇인가요? - Apple M1 Pro 2 - Apple M1 Max 1 - Apple M1 2 #### 애플이 새로 출시한 매킨토시 컴퓨터에서 iOS의 애플리케이션을 실행할 수 있는 이유는 무엇일까요? - 동일 타입의 프로세서를 사용하기 때문에 이를 가능하게 하는 주요 기술은 "Apple Silicon" 칩 및 "Universal Control" 기능입니다. Apple Silicon: Apple은 매킨토시 컴퓨터에 사용되는 기존의 Intel 프로세서 아키텍처에서 자체 설계한 Apple Silicon 칩으로 전환하였습니다. Apple Silicon은 동일한 ARM 아키텍처를 기반으로 iOS, iPadOS, macOS 운영체제를 모두 실행할 수 있도록 설계되었습니다. 이로 인해 iOS 애플리케이션은 Mac 컴퓨터에서 직접 실행될 수 있게 되었습니다. Universal Control: macOS Monterey부터는 Universal Control이라는 기능이 도입되었습니다. Universal Control은 사용자가 맥, 아이패드, 맥북 등 여러 디바이스를 동시에 사용할 수 있게 해주는 기능으로, 키보드와 마우스를 공유하거나 마우스를 디바이스 간에 이동하여 연결된 디스플레이를 공유할 수 있습니다. 따라서 사용자는 매킨토시 컴퓨터에서 iOS 애플리케이션을 실행하면서 iOS와 macOS 간의 시스템 간 이동이 더욱 원활하게 가능해집니다. #### 이전의 매킨토시 컴퓨터에서는 불가능했던 이유는 무엇일까요? - CPU가 다르기 때문에(Intel) 이전의 매킨토시 컴퓨터는 Intel 프로세서 아키텍처를 사용하고 있었고, iOS 기기는 ARM 프로세서 아키텍처를 사용하고 있었습니다. 두 아키텍처는 서로 다르기 때문에, iOS 애플리케이션은 ARM 아키텍처에 최적화되어 있었고, Intel 아키텍처에서는 직접 실행할 수 없었습니다. #### 프로세서를 위한 프로세스 스케쥴링 방식에는 어떤 것이 있는지 간략히 알아봅시다. - 선입선출(FIFO) 스케줄링: 가장 간단한 스케줄링 알고리즘으로, 작업이 도착한 순서대로 실행됩니다. 먼저 도착한 작업이 먼저 실행되기 때문에 공정성이 보장됩니다. 하지만 작업의 실행 시간에 상관없이 우선순위를 고려하지 않기 때문에, 실행 시간이 오래 걸리는 작업이 다른 작업들의 실행을 지연시킬 수 있습니다. - 우선순위 스케줄링: 각 작업에 우선순위를 할당하고, 우선순위가 높은 작업을 먼저 실행하는 방식입니다. 우선순위는 작업의 중요도나 긴급성에 따라 할당됩니다. 우선순위 스케줄링은 시스템 리소스를 효율적으로 활용할 수 있지만, 우선순위 부여에 주의를 기울여야 합니다. 너무 낮은 우선순위 작업은 실행을 지연시킬 수 있고, 너무 높은 우선순위 작업은 다른 작업들을 제한할 수 있습니다. - 라운드 로빈(Round Robin) 스케줄링: 작업들이 동일한 시간 슬라이스(타임 슬라이스)를 할당받고, 할당된 시간이 지나면 다음 작업으로 전환되는 방식입니다. 각 작업은 일정 시간 동안 실행되며, 시간이 초과되면 다른 작업으로 넘어갑니다. 라운드 로빈 스케줄링은 공정성을 보장하고 응답성을 향상시킬 수 있습니다. 하지만 작업의 실행 시간이 긴 경우에는 문제가 발생할 수 있습니다. - 다단계 큐(Multi-level Queue) 스케줄링: 작업들을 여러 개의 큐에 그룹화하고, 각 큐에 다른 우선순위를 할당하는 방식입니다. 각 큐는 다른 스케줄링 알고리즘을 사용할 수 있습니다. 예를 들어, 우선순위가 높은 큐는 우선순위 스케줄링을 사용하고, 낮은 큐는 라운드 로빈 스케줄링을 사용할 수 있습니다. 다단계 큐 스케줄링은 다양한 종류의 작업을 효율적으로 처리할 수 있지만, 큐 간의 상호작용과 자원 할당에 대한 설계와 관리가 필요합니다. #### 운영체제 입장에서 다양한 프로세스를 스케쥴링하는 규칙을 만들어봅시다. - 사용자가 우선순위를 설정할 수 있게 함(우선순위가 높은 태스크가 최우선) - 다단계 큐 기반으로 통합 관리 큐가 존재 - 세부적으로 특성에 따라 다른 스케줄링 알고리즘 반영 - 추가적으로 우선순위 **학습** 시키기 #### 앞으로 iOS와 macOS는 통합될까요? - Maybe!!(Apple 마음🤷‍♀️)