CS/컴퓨터구조

[컴퓨터구조] CPU 설계 기법 (1)

nowkoes 2023. 6. 12. 15:25

<본 카테고리는 "혼자 공부하는 컴퓨터구조 + 운영체제" 책과 강의를 기반으로 작성하였습니다>


코어와 스레드

클럭

 이번 시간에는 CPU 성능 향상에 대한 다양한 전략들을 알아보도록 하자. 우선 클럭에 대해 알아보자. 클럭은 CPU의 작동 원리를 다룰 때 클럭에 대해 잠깐 설명했었다. 

 

클럭에 대한 설명

 

 컴퓨터의 여러 부품들은 클럭 신호에 의존하여 동작한다. 이 신호는 CPU의 명령어 사이클, 즉 명령어를 처리하는 순서와 속도를 제어한다. 클럭의 단위는 헤르츠(Hz)이며, 이는 1초 동안 클럭이 반복되는 횟수를 나타낸다. 따라서 클럭의 속도가 높아질수록 CPU는 명령어 사이클을 더 빠르게 수행하게 되며, 이는 다른 부품들이 더 빠르게 작동하도록 한다. 그렇다면 클럭 속도를 무작정 높이면 CPU가 빨라질까?

 

 이에 대한 답은 '부분적으로 빨라진다'이다. 클럭 속도를 강제로 증가시키는 오버클럭킹(Overclocking) 기법은 일정 수준의 성능 향상을 가져올 수 있지만, 발열 문제나 과부하와 같은 위험성을 야기하기도 한다. 또한, CPU의 아키텍처, 메모리 속도, 버스 속도 등 다른 여러 요소가 CPU의 성능에 크게 영향을 미치기 때문에  클럭 속도를 무조건적으로 높이는 것만으로는 CPU 성능 향상에 한계가 있음을 명심해야 한다. 따라서, 클럭 속도를 증가시키는 것이 CPU의 성능 향상에 도움이 되긴 하지만, 클럭 속도만으론 한계가 있다.


코어와 멀티 코어

인텔 i5 코어 출처: 구글

 

 컴퓨터를 구매하기 위해 여러 사양을 체크할 때, CPU를 보면 N코어 M스레드와 같은 용어를 쉽게 볼 수 있다. 이때 코어(Core)CPU의 작업 처리 단위, 즉 프로세서를 의미한다. 각 코어는 독립적으로 명령어를 실행할 수 있으며, 이런 코어가 여러 개 모인 것멀티코어 CPU 혹은 멀티코어 프로세서라고 부른다. 다시 말해, 전통적으로 CPU라고 알고 있던 것이 현대에 이르러선 사실상 코어라는 것이다. 

 

 그렇다면 코어도 무작정 늘리면 처리 속도가 그에 비례해서 늘어날까? CPU의 연산 속도가 꼭 코어 수에 비례하여 증가하지는 않는다. CPU의 연산 속도는 코어마다 적절히 분배된 작업량에 따라 달라지는데, 이는 조별 과제에서 모든 구성원이 동시에 작업할 수 있는 일이 아니라면, 인원수가 많아도 과제 완성 시간이 줄어들지 않는 것과 비슷하다. 또한, 처리해야 하는 작업의 규모보다 코어 수가 지나치게 많다면, 그 코어들이 활용되지 않아 성능 향상에 도움이 되지 않는다. 중요한 것은 각 코어에 얼마나 효율적으로 명령어들을 분배하느냐이다. 이는 작업의 병렬 처리 가능성과 프로그램의 최적화 수준, 운영 체제의 스케줄링 등에 의해 결정된다.


스레드와 멀티스레드

 이번에는 스레드와 멀티스레드에 대해 알아보자. 스레드(thread)프로그램에서 실행 흐름의 최소 단위를 의미한다. 이는 다소 추상적으로 느껴질 수 있다. 따라서 스레드를 이해하기 위해선 이를 하드웨어적 스레드와 소프트웨어적 스레드 두 가지 관점으로 나누어 살펴보는 것이 도움이 된다.

 

하드웨어적 스레드

출처: 위키백과

 

 스레드를 하드웨어적으로 정의하면, 하나의 코어가 동시에 처리하는 명령어 단위를 의미한다. 예를 들어 4 코어 4 스레드라고 하면, 4개의 코어가 각각 한 번에 하나의 명령어를 명령어를 실행하는 부품인 코어를 4개 포함하고, 한 번에 1개의 명령어를 처리할 수 있다는 것을 의미한다. 이처럼 하나의 코어로 여러 명령어를 동시에 처리하는 CPU멀티스레드 프로세서 또는 멀티스레드 CPU라고 부른다. 

 

소프트웨어적 스레드

 스레드를 소프트웨어적으로 정의하면, 하나의 프로그램에서 독립적으로 실행되는 단위를 의미한다. 하나의 프로그램은 실행되는 과정에서 한 부분만 실행될 수도 있지만, 프로그램의 여러 부분이 동시에 실행될 수도 있다. 이러한 기능을 가진 코드를 각각의 스레드로 만들면 동시에 실행할 수 있다.

 

 이를 이해하기 위해 C++에서 thread 라이브러리를 이용해 멀티스레딩을 간단하게 구현한 코드를 살펴보자. 두 수를 입력받아 사칙연산을 수행하는 기능을 각각의 스레드에서 동시에 실행하는 예제를 만들 수 있다.

 

#include <iostream>
#include <thread>
using namespace std;

void add(double num1, double num2) 
{
    cout << "덧셈 결과: " << num1 + num2 << "\n";
}

void subtract(double num1, double num2) 
{
    cout << "뺄셈 결과: " << num1 - num2 << "\n";
}

void multiply(double num1, double num2) 
{
    cout << "곱셈 결과: " << num1 * num2 << "\n";
}

void divide(double num1, double num2) 
{
    if (num2 != 0)
        cout << "나눗셈 결과: " << num1 / num2 << "\n";

    else
        cout << "0으로는 나눌 수 없습니다." << "\n";
}

int main() 
{
    double num1, num2;
    cout << "두 수를 입력하세요: ";
    cin >> num1 >> num2;

    thread t1(add, num1, num2);
    thread t2(subtract, num1, num2);
    thread t3(multiply, num1, num2);
    thread t4(divide, num1, num2);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

실행 결과

 

 위 코드에서 각 함수는 별도의 스레드에서 동시에 수행된다. join() 함수는 메인 스레드가 해당 스레드의 실행이 끝날 때까지 기다리도록 한다. 이 코드를 실행하면 입력받은 두 수에 대한 사칙연산의 결과가 동시에 출력된다.

 

멀티스레드

 

 하나의 코어로 여러 명령어를 동시에 처리하는 멀티스레드 프로세서를 실제로 설계하는 일은 매우 복잡하다. 이를 가능하게 하는 핵심 요소 중 하나는 CPU 내부의 레지스터다. CPU에는 명령어를 실행하는 데 필요한 다양한 정보를 저장하는 레지스터들이 있다. 이러한 레지스터를 각 스레드별로 분리하거나 공유하는 등의 방식으로 여러 스레드의 동시 실행을 지원하게 된다. 이는 프로그램 입장에서 봤을 때 한 번에 하나의 명령어를 처리하는 CPU가 여러 개 있는 것처럼 보여서, 논리 프로세서라고 부르기도 한다.


요약

클럭
1. 정의: 컴퓨터에서 특정한 간격으로 발생하는 신호
2. 단위: Hz

코어와 스레드
1. 코어: CPU의 작업 처리 단위
2. 스레드
 a. HW 스레드: 하나의 코어가 동시에 처리하는 명령어 단위
 b. SW 스레드: 하나의 프로그램에서 독립적으로 실행되는 단위
3. 멀티코어 vs 멀티스레드
- 멀티코어는 명령어를 실행할 수 있는 HW 부품이 CPU 안에 두 개 이상 있는 CPU, 멀티스레드는 하나의 코어로 여러 개의 명령어를 동시에 실행할 수 있는 CPU
반응형