CPU는 초당 수십억 번 이상의 연산을 수행 한다.
CPU가 매우 빠르게 두 프로그램의 코드를 번갈아 수행한다면 사람이 느낄 때 두 프로그램이 동시에 실행되는 것 처럼 느껴질 것이다.
cpu는 대략 0.01초 단위로 돌아가며 실행한다.
컴퓨터 시스템에서 둘 이상의 프로세서를 사용하여 여러 작업을 동시에 처리하는 기술을 의미한다.
시스템은 하나의 CPU 코어만을 사용하는 시스템보다 동시에 더 많은 작업을 처리할 수 있다.
멀티프로세싱은 하드웨어 장비의 관점이고, 멀티태스킹은 운영체제 소프트웨어의 관점이다.
멀티프로세싱
여러 CPU 코어를 사용하여 동시에 여러 작업을 수행하는 것을 의미한다.
하드웨어 기반으로 성능을 향상시킨다.
멀티태스킹
단일 CPU 코어가 여러 작업을 동시에 수행하는 것처럼 보이게 하는 것을 의미한다.
소프트웨어 기반으로 CPU 시간을 분할하여 각 작업에 할당한다.
프로그램을 실행하면 프로세스가 만들어지고 프로그램이 실행된다.
이렇게 운영체제 안에서 실행중인 프로그램을 프로세스라고 한다.
각 프로세스는 독립적인 메모리 공간을 갖고 있으며, 운영체제에서 별도의 작업 단위로 분리해서 관리된다.
각 프로세스는 별도의 메모리 공간을 갖고 있기 때문에 서로 간섭하지 않는다.
그리고 프로세스가 서로의 메모리에 직접 접근할 수 없다.
프로세스는 이렇게 서로 격리되어 관리되기 때문에, 하나의 프로세스가 충돌해도 다른 프로세스에 영향을 미치지 않는다.

프로세스는 하나 이상의 스레드를 반드시 포함한다.
스레드는 프로세스 내에서 실행되는 작업의 단위다.
한 프로세스 내에서 여러 스레드가 존재할 수 있으며, 이들은 프로세스가 제공하는 동일한 메모리 공간을 공유한다.
스레드는 프로세스보다 단순하므로 생성 및 관리가 단순하고 가볍다.
단일 스레드는 한 프로세스 내에 하나의 스레드만 존재하는 것이고
멀티 스레드는 한 프로세스 내에 여러 스레드가 존재하는 것이다.
CPU에 어떤 프로그램이 얼마만큼 실행될지는 운영체제가 결정하는데 이것을 스케줄링이라 한다.
이때 단순히 시간으로만 작업을 분할하지는 않고, CPU를 최대한 활용할 수 있는 다양한 우선순위와 최적화 기법을 사용한다.
운영체제는 내부에 스케줄링 큐를 가지고 있고, 각각의 스레드는 스케줄링 큐에서 대기한다.


멀티태스킹이 반드시 효율적인 것은 아니다.
CPU 코어는 하나가 있고 스레드A, 스레드B가 있다. (cpu1개에 스레드2개)
운영체제는 스레드A를 실행한다. 멀티태스킹을 해야 하기 때문에 스레드A를 계속 실행할 수 없다. 따라서 스레드A를 잠시 멈추고 스레드B를 실행한다.
이후 스레드B를 멈추고 스레드A로 다시 돌아가려고 할 때 CPU는 그냥 다시 돌아갈 수 없다.
스레드A의 코드가 어디까지 수행되었는지 위치를 찾아야 한다. 그리고 계산하던 변수들의 값을 CPU에 다시 불러들여야 한다.
따라서 스레드A를 멈추는 시점에서 사용하던 값들을 메모리에 저장해두어야 한다. 그리고 이후 스레드A를 다시 실행할 때 이 값들을 CPU에 다시 불러와야 한다.
이러한 과정들을 컨텍스트 스위칭이라고 한다.
컨텍스트 스위칭 과정에서 이전에 실행 중인 값을 메모리에 잠깐 저장하고
이후에 다시 실행하는 시점에 저장한 값을 CPU에 다시 불러와야 한다.
결과적으로 컨텍스트 스위칭 과정에는 약간의 비용이 발생한다.
각각의 스레드가 하는 작업은 크게 2가지로 구분할 수 있다.
CPU의 연산 능력을 많이 요구하는 작업을 의미한다.
이러한 작업은 주로 계산, 데이터 처리, 알고리즘 실행 등 CPU의 처리 속도가 작업 완료 시간을 결정하는 경우다.
복잡한 수학 연산, 데이터 분석, 비디오 인코딩, 과학적 시뮬레이션 등
디스크, 네트워크, 파일 시스템 등과 같은 입출력(I/O) 작업을 많이 요구하는 작업을 의미한다.
이러한 작업은 I/O 작업이 완료될 때까지 대기 시간이 많이 발생하며, CPU는 상대적으로 대기 상태에 있는 경우가 많다. 쉽게 이야기하면 스레드가 CPU를 사용하지 않고 I/O 작업이 완료될 때 까지 대기한다.
데이터베이스 쿼리 처리, 파일 읽기/쓰기, 네트워크 통신, 사용자 입력 처리 등.
실무에서는 CPU-바운드 작업보다 I/O-바운드 작업이 많다.
예를 들어, 백엔드 개발자는 웹 애플리케이션 서버를 개발하면서 주로 사용자의 입력을 기다리거나 데이터베이스를 호출하는 등, 대기하는 작업이 많다.
일반적인 자바 웹 애플리케이션 서버는 사용자의 요청 하나를 처리하는데 1개의 스레드를 사용하며, 동시에 여러 사용자의 요청을 처리하려면 그만큼 스레드가 필요하다.
만약 사용자의 요청을 처리하는데 CPU를 1%만 사용하고 대부분 대기하는 상황이라면, CPU 코어 수에 맞추어 스레드 수를 설정하면 비효율적이다.
예를 들어, 4개의 CPU 코어가 있다고 스레드를 4개로 설정하면, CPU는 4%만 사용되고 나머지 96%는 놀게 된다. 대신, 스레드 수를 늘려 100개로 설정하면 동시에 100명의 사용자 요청을 처리할 수 있어 CPU 자원을 더 효율적으로 사용할 수 있다.
따라서 성능 테스트를 통해 최적의 스레드 수를 찾는 것이 중요하며, 단순히 장비를 업그레이드하는 것이 해결책이 아닐 수 있다. CPU 자원을 최대한 활용하기 위해서는 스레드 수를 적절히 조정해야 한다.