[운영체제] CPU 도 예측하고 미리 움직인다 (1)

CPU가 성능을 높이는 방법으로 클럭속도를 높이거나 코어 개수를 늘립니다. 그러나 내부적으로 보면 더 재밌는 이야기가 숨어 있습니다. 바로 예측해서 연산한다는 것입니다.

 

https://youtu.be/Fnvlujxbqss?si=b2_xivl4myIgkjyQ


CPU와 RAM 사이의 속도 차이

 

CPU는 연산장치이며, 중요한 것은 속도이다. 속도가 빠를수록 연산의 양이 늘어나고 처리 성능이 좋아진다. 그래서 클럭 속도를 높이는 방향으로 개발이 진행되다가, 최근에는 코어의 개수를 증가시키는 방식으로 발전하고 있다. CPU의 코어가 연산을 담당하며, 연산에 필요한 데이터는 기본적으로 RAM에 저장된다. 이 데이터를 CPU의 영역으로 옮기고, 연산 후 다시 RAM으로 돌려보내는 작업을 반복한다. 문제는 CPU와 RAM의 속도 차이가 크다는 점이다.

CPU 코어의 레지스터는 데이터 접근 시간이 약 1ns(nano sec)인 반면, RAM은 50ns가 걸린다. 약 50배의 속도 차이가 난다. 만약 어떤 사람과 이야기 하는데 말을 50배 느리게 알아듣고, 50배 느리게 대답한다면 정상적인 대화를 하기 어려울 것이다. 이와 유사하게, CPU와 RAM 사이에도 속도 차이가 큰 문제가 발생한다.

 

캐시 cache


이 문제를 해결하기 위해 중간에 완충 역할을 하는 개념이 필요하다. 그 역할을 하는 것이 캐시(cache)이다. RAM이 하드디스크나 외부 메모리와의 완충 장치 역할을 한다면, 캐시는 CPU와 RAM 사이의 완충 역할을 한다. 캐시는 자주 사용되는 데이터를 미리 저장하여 CPU가 빠르게 접근할 수 있게 함으로써, 속도 차이를 줄이고 전체 시스템 성능을 향상시킨다.

 

캐시의 종류는 3개가 있다. 코어마다 L1, L2가 붙어있고, L3는 공통으로 쓰는 경우가 많다. 예를 들어 코어 4개가 있다고 하면 각각의 코어마다 L1,L2 가 각각 붙어있다(CPU 제조사마다 차이가 있지만 대부분). 이들을 캐시 메모리라 하며 속도차이를 줄여주는 역할을 한다.

 

"명령어 캐시"와 "데이터 캐시"는 L1 캐시의 하위 유형이며, L2 캐시는 통합된 캐시로 사용

 

L1, L2, L3로 나눠놓은 이유는 데이터의 양 때문이다. L1데이터는 명령과 데이터가 섞여있지만, L2는 데이터와 명령이 다 섞여있다. L3는 코어 여러개로 갈 것이 몽땅 다 들어가 있다. 연산을 할 때, 연산 = "명령" + "데이터" 인데, 이를 보통 L1캐시 쪽에서 처음 찾게 된다.

 

코어(CPU) 의 예측이라고 하는 것은 바로 이 캐시에서 일어난다.

 

L1 캐시:

  • 일반적으로 L1 은 명령어 캐시, 데이터 캐시로 나누어지며 독립적으로 운영된다.
  • 명령어 캐시 (Instruction Cache): CPU가 실행할 명령어들을 저장하는 캐시. 프로그램 코드의 명령어를 빠르게 읽어올 수 있도록한다.
  • 데이터 캐시 (Data Cache): 프로그램이 처리하는 데이터들을 저장하는 캐시. 주로 변수, 배열, 데이터 구조 등의 데이터를 빠르게 접근할 수 있도록 한다.

L2 캐시:

  • L2 캐시는 L1 캐시보다 크지만 상대적으로 느리다. L1 캐시에서 미스가 발생할 경우 L2 캐시에서 데이터를 찾게 된다.
  • L2 캐시는 일반적으로 명령어와 데이터를 모두 저장할 수 있는 통합된 캐시로 운영

L3 캐시:

  • L3 캐시는 여러 CPU 코어가 공유하는 캐시로, L2 캐시보다 더 크고 느리다.
  • 주로 멀티코어 프로세서에서 사용되며, 각 코어의 L2 캐시에서 미스가 발생할 경우 L3 캐시에서 데이터를 찾는다.

 


캐시 메모리의 역할 (캐시에서 일어나는 예측)

예를 들어

for (int i = 0; i < 100; i++) {
    // 반복문 안에서 수행할 작업
}

이런 연산이 있다고 하자. 

 

위에서는 자료형이 `int`인 데이터가 100개 필요하다. 이 데이터에 대해 반복문을 사용하여 연산을 수행할 때, 반복 변수 `i`는 0에서 시작하여 1, 2로 증가한다. 반복문 내에서 비교하는 상수는 100이다. CPU는 이 상수를 알고 있기 때문에, 앞으로 `int` 97개를 추가로 처리해야 한다는 것을 예측한다.

이 예측을 바탕으로, CPU는 필요한 데이터를 RAM(주 기억 장치)에서 L3, L2 캐시로 미리 가져오기 시작한다. CPU는 연산을 수행하면서 RAM에게 바로 요청하지 않고, 먼저 캐시에 요청한다. "RAM 메모리 주소 어딘가에 있는 데이터를 가져오려 해"라며 캐시에게 요청하면, L1 캐시는 "그럴 줄 알고 미리 갖다놨지롱!"이라며 필요한 데이터를 CPU에게 제공한다. CPU 는 실제 RAM 과 IO를 하지 않고 그 int 로 연산을 수행한다. CPU는 이렇게 예측을 통해 작동함으로써 성능을 높인다.

 

 

예측이라고 하는 것이 항상 맞을 수는 없다. 캐시의 예측이 틀릴 때가 있고 맞을 때가 있는데, 맞는 경우는 캐시 히트, 틀린 경우는 캐시 미스 라고 한다.

 

캐시 히트 (Cache Hit)

  • 정의: CPU가 필요한 데이터를 캐시(주로 L1, L2, L3 캐시)에서 찾을 때 발생

캐시 미스 (Cache Miss)

  • 정의: CPU가 필요한 데이터를 캐시에서 찾지 못하고, 주 기억 장치(RAM)에서 가져와야 할 때 발

 

 

참고로 예측의 정확도는 90% 이상이라고 한다. 


ref: https://velog.io/@jinh2352/%EB%A9%80%ED%8B%B0%EC%BD%94%EC%96%B4%EC%97%90%EC%84%9C%EC%9D%98-%EC%BA%90%EC%8B%9C-coherency-%EB%B3%B4%EC%9E%A5-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C

 

멀티코어에서의 캐시 / coherency 보장 프로토콜

멀티코어에서 캐시는 각 코어가 쓰는 전용 캐시(private cache)와 여러 코어가 공유하는 공유 캐시(shared cache)가 있다. 각 코어에는 명령어 및 데이터 1차 레벨 캐시가 독립적으로 들어있다. 그리고 L2

velog.io