사전 코어
개념

코어

gabury1

코어는 프로세서 안에서 명령을 하나씩 꺼내 실행하는 단위입니다. 프로세서 한 개에 이 단위를 여럿 넣으면 서로 다른 일을 같은 순간에 진행할 수 있습니다. 한 대의 서버가 몇 갈래의 일을 실제로 동시에 굴릴 수 있는지를 이 수가 정합니다.

쉽고 빠른 이해

코어는 프로세서 안에 든 작은 실행 기계 하나입니다. 명령을 꺼내 뜻을 풀고 계산한 뒤 결과를 남기는 일을 혼자 끝냅니다.

한 코어의 속도를 올리는 길은 열과 전력에서 막혔습니다. 그래서 속도를 올리는 대신 같은 코어를 여럿 넣는 쪽으로 갔습니다.

도는 순서는 이렇습니다:

  1. 운영체제가 실행할 일을 골라 코어에 얹습니다
  2. 코어는 그 일의 명령을 차례로 꺼내 실행합니다
  3. 시간이 다 되면 운영체제가 그 일을 내리고 다른 것을 얹습니다

대가도 있습니다. 코어를 늘려도 갈라지지 않는 구간은 줄지 않습니다. 코어들은 캐시와 메모리를 함께 씁니다. 그래서 서로 기다리는 구간이 생깁니다.

상세

이삿짐을 넷이 나눠 들면 방 넷이 한꺼번에 빕니다. 짐을 안고 나온 사람들은 엘리베이터 앞에 한 줄로 섭니다. 사람을 더 불러도 엘리베이터는 한 대입니다.

CPU(Central Processing Unit, 중앙처리장치)는 프로그램의 명령을 실행하는 칩입니다. 코어는 그 칩 안에서 실행을 맡는 부분입니다. 명령 하나를 꺼내 뜻을 풀고 계산해 결과를 남기는 회로 한 벌이 코어 하나입니다.

코어는 그 일을 혼자 끝까지 해냅니다. 그래서 코어 하나는 명령의 흐름 하나를 붙들고 갑니다. 코어가 넷이면 흐름 넷이 같은 순간에 나아갑니다. 이런 성질을 병렬성이라고 합니다.

코어 한 벌의 구성

코어 안에는 계산을 맡는 연산 장치가 있습니다. 값을 잠깐 쥐어 두는 레지스터도 코어마다 따로 있습니다. 다음에 실행할 명령이 어느 주소에 있는지는 프로그램 카운터가 들고 있습니다.

이 셋이 코어마다 따로 있다는 것이 코어를 코어이게 합니다. 흐름 하나가 어디까지 갔는지를 코어가 스스로 기억한다는 뜻이기 때문입니다. 옆 코어가 무엇을 하든 자기 명령을 이어 갑니다.

코어에 얹혀 도는 실행 흐름 하나를 스레드라고 부릅니다. 아래에서는 이 이름을 씁니다.

칩 안의 코어 배치

코어는 칩 안에 여러 벌이 나란히 놓입니다. 코어마다 자기만 쓰는 작은 CPU 캐시(전용 캐시)가 붙고, 그 아래에는 모든 코어가 함께 쓰는 큰 캐시가 있습니다. 메모리(메인 메모리)로 나가는 길목에는 메모리 컨트롤러가 하나 있어 코어들의 요청을 받아 넘깁니다.

flowchart TD
    subgraph CHIP["프로세서 칩"]
        subgraph C1["코어 1"]
            E1["연산 장치 · 레지스터 · 프로그램 카운터"]
            V1["전용 캐시"]
        end
        subgraph C2["코어 2"]
            E2["연산 장치 · 레지스터 · 프로그램 카운터"]
            V2["전용 캐시"]
        end
        SHARED["모든 코어가 함께 쓰는 캐시"]
        MC["메모리 컨트롤러"]
    end
    MEM["메인 메모리"]
    E1 --> V1
    E2 --> V2
    V1 --> SHARED
    V2 --> SHARED
    SHARED --> MC
    MC --> MEM

그림은 코어 둘만 그렸습니다. 코어가 여덟이면 같은 상자가 여덟 벌 들어가고, 아래쪽 캐시와 메모리 컨트롤러는 그대로 하나씩입니다. 코어는 늘어나는데 메모리로 나가는 길은 그대로라는 모양이 여기서 나옵니다.

물리 코어와 논리 코어

운영체제가 세는 코어 수는 칩에 든 회로 수와 다를 수 있습니다. 하이퍼스레딩을 켠 칩은 코어 하나를 둘처럼 보여 줍니다. 코어가 메모리를 기다리며 노는 구간에 다른 스레드의 명령을 끼워 넣는 방식입니다.

이렇게 늘어나 보이는 쪽을 논리 코어, 칩에 실제로 든 쪽을 물리 코어라고 부릅니다. 논리 코어 둘은 한 코어의 연산 장치를 나눠 씁니다. 그래서 계산만 계속하는 일이라면 논리 코어가 둘이어도 한 벌이 일하는 것과 크게 다르지 않습니다.

flowchart TD
    subgraph PC["물리 코어 하나"]
        LC1["논리 코어 1"]
        LC2["논리 코어 2"]
        ALU["연산 장치 · 한 벌"]
    end
    LC1 --> ALU
    LC2 --> ALU
    PC --> OS["운영체제가 세는 코어 수 = 2"]

코어를 늘려도 남는 병목

병목은 세 갈래입니다. 갈라지지 않는 구간, 코어들이 함께 쓰는 길목, 그리고 여러 코어가 함께 만지는 데이터입니다.

일을 갈라 코어에 나눠 주려면 갈라지는 부분이 있어야 합니다. 앞의 결과가 나와야 다음을 할 수 있는 구간은 코어가 몇이든 한 코어가 순서대로 밟습니다. 전체 시간이 이 구간 아래로는 안 내려간다는 것이 암달의 법칙입니다.

block-beta
    columns 6
    R1["코어 1"] S1["갈라지지 않는 구간"] P1["갈라지는 구간"]:4
    R4["코어 4"] S4["갈라지지 않는 구간"] P4["갈라지는 구간"] space:3

코어를 넷으로 늘려 짧아지는 쪽은 뒤 칸뿐입니다. 앞 칸은 그대로 남습니다.

코어들이 함께 쓰는 것도 병목이 됩니다. 아래쪽 캐시와 메모리 대역폭은 코어 수만큼 같이 늘어나지 않습니다. 코어가 많아질수록 같은 길목에서 서로를 기다립니다.

같은 데이터를 여러 코어가 만질 때도 대가가 붙습니다. 코어마다 자기 캐시에 복사본을 들고 있습니다. 한쪽이 값을 고치면 다른 쪽 복사본을 무르게 해야 합니다. 이 맞추는 일을 캐시 일관성이라고 합니다.

캐시는 값을 하나씩 옮기지 않습니다. 정해진 크기의 덩이 단위로 옮깁니다. 그래서 서로 다른 변수를 고쳐도 그 변수들이 한 덩이에 담겨 있으면 맞춤이 일어납니다. 이것을 거짓 공유라고 부릅니다.

flowchart TD
    subgraph LINE["메모리의 한 덩이"]
        VA["변수 A"]
        VB["변수 B"]
    end
    subgraph K1["코어 1 — 변수 A 를 고친다"]
        CP1["덩이 복사본"]
    end
    subgraph K2["코어 2 — 변수 B 를 고친다"]
        CP2["덩이 복사본"]
    end
    LINE --> CP1
    LINE --> CP2
    CP1 -->|"옆 복사본을 무르게 한다"| CP2
    CP2 -->|"옆 복사본을 무르게 한다"| CP1

고치는 자리는 다른데 오가는 단위는 같은 한 덩이입니다. 데이터를 어떻게 배치했느냐에 따라 코어를 늘린 값을 못 받는다는 뜻입니다.

여러 코어가 같은 데이터를 고칠 때 순서를 세우는 장치를 락이라고 합니다. 한 코어가 락을 쥐고 있는 동안 나머지는 기다립니다. 코어를 늘려도 이 구간에서는 대기만 늘어납니다.

서버에서 쓰는 코어 수

서버 프로세스는 대개 스레드를 여럿 띄워 요청을 처리합니다. 같은 순간에 계산이 진행되는 갈래 수는 코어 수를 넘지 못합니다. 스레드를 그보다 많이 만들면 나머지는 차례를 기다리고, 운영체제의 스케줄러가 이들을 번갈아 코어에 얹습니다.

바꿔 얹는 데도 시간이 듭니다. 이 교대를 컨텍스트 스위치라고 합니다.

스레드 풀은 스레드를 미리 만들어 두고 돌려 쓰는 묶음입니다. 계산이 대부분인 일이면 이 묶음의 크기를 코어 수 언저리로 잡습니다. 반대로 시간의 대부분을 응답을 기다리며 보내는 일이면 스레드를 코어 수보다 많이 두어도 코어가 놀지 않습니다.

컨테이너로 돌릴 때는 코어를 통째로 주지 않고 몫으로 나눠 줍니다. 한 코어의 절반만큼을 주면 그 프로세스는 정해진 시간 동안만 코어를 쓰고 나머지 시간은 멈춰 섭니다. 호스트에 코어가 많아도 이 몫이 작으면 프로세스가 쓸 수 있는 계산량은 그 몫까지입니다.

block-beta
    columns 4
    T["한 주기"]:4
    U["코어를 쓴다"]:2 W["멈춰 선다"]:2

몫은 코어의 조각이 아니라 한 주기 안의 시간입니다.

이름만 같은 다른 코어

코어 덤프의 코어는 이 코어가 아닙니다. 프로그램이 죽은 순간의 메모리 내용을 파일로 남긴 것입니다. 이름은 옛 메모리 장치에서 왔습니다.

제품 이름 뒤에 붙는 코어도 다릅니다. 그 소프트웨어의 중심 부분, 곧 곁가지를 뺀 알맹이를 가리킵니다.

관련 항목

코어가 들어앉는 상위 장치

CPU · 프로세서 · 멀티코어 · SoC · GPU · CPU 소켓

코어 하나를 이루는 부품

레지스터 · 프로그램 카운터 · ALU · CPU 파이프라인 · 명령어 집합 · 분기 예측 · L1 캐시

코어 위에서 도는 실행 단위

스레드 · 프로세스 · 논리 코어 · 하이퍼스레딩 · 스케줄러 · 컨텍스트 스위치 · CPU 어피니티 · 타임 슬라이스

코어가 여럿이라 생기는 문제

캐시 일관성 · 거짓 공유 · 캐시 핑퐁 · 경쟁 조건 · 메모리 장벽 · NUMA · 락 경합

코어 수로 설명하는 성질

병렬성 · 동시성 · 암달의 법칙 · 처리량 · 멀티스레딩 · 스케일 업

코어 몫을 나누고 재는 수단

cgroup · CPU 사용률 · 로드 애버리지 · 스레드 풀 · CPU 할당량 · CPU 스로틀링

이름이 겹치는 이웃

코어 덤프 · 코어 메모리 · 코어 프로파일 · 코어 웹 바이탈

다른 이름: core · CPU 코어 · CPU core · 프로세서 코어 · 물리 코어