[CS] 폭발적인 병렬처리기법 ~ 파이프라이닝!

박동현·2024년 12월 2일
5

빠른 CPU를 만들기 위해 CPU를 쉬지않게 만들어보겠다.

-~챕터 1 : 명령어 파이프라인~-

명령어 파이프라인을 알아보기 앞서, 하나의 명령어가 처리되는 전체 과정을 비슷한 시간 간격으로 나누어 보자. 명령어 처리 과정을 클럭 단위로 나누어 보면 일반적으로 다음과 같이 나눌 수 있다.

1 . 명령어 인출
2 . 명령어 해석
3 . 명령어 실행
4. 결과 저장

여기서 중요한 점은 같은 단계가 겹치지만 않는다면 CPU는 각 단계를 동시에 실행 할 수 있다.

무슨 말인지 한번 살펴보자.

CPU는 명령어를 다음과 같이 처리한다.

하지만 명령어 파이프라이닝 기법을 사용하면 다음과 같이 처리할 수 있다.

처음보다 효율적으로 처리할 수 있단 것을 알 수 있다.

파이프라이닝이 높은 성능을 가져오기는 하지만, 특정 상황에서는 성능 향상에 실패하는 경우도 있다! 이러한 상황을 파이프라인 위험이라고 한다.

-~챕터 2 : 파이프라인 위험~-

파이프라인 위험에는 크게 데이터 위험, 제어 위험, 구조적 위험이 있다.

-~챕터 2-1 : 데이터 위험~-

데이터 위험은 명령어 간 데이터 의존성에 의해 발생한다.
모든 명령어를 동시에 처리할 수는 없다.

어떤 명령어는 이전 명령어를 끝까지 실행해야만 실행할 수 있는 경우가 있다.

예를 들어 다음과 같은 명령어가 있다.
R은 레지스터를 뜻함.

명령어 1 : R1 = R2 + R3
명령어 2 : R4 = R1 + R5

명령어 1를 실행해야만 명령어 2를 수행할 수 있다.
만약 명령어 1의 실행이 끝나기 전에 명령어 2를 인출하면 원치않은 R1 값을 읽어들일 수 있다. 따라서 명령어 2는 명령어 1의 데이터에 의존적이다.
이처럼 데이터 의존성에 의해 파이프라인이 제대로 작동하지 않는 것을 데이터 위험이라고 한다.

-~챕터 2-2 : 제어 위험~-

제어 위험은 주로 분기 등으로 인한 프로그램 카운터의 갑작스러운 변화에 의해 발생한다.
기본적으로 프로그램 카운터는 현재 실행 중인 명령어의 다음 주소를 가르킨다.
하지만 프로그램 실행 흐름이 바뀌어 ex) 인터럽트 명령어가 실행되면서 프로그램 카운터 값에 갑작스러운 변화가 생긴다면 명령어 파이프라인에서 이미 처리 중이던 명령어들은 쓸모가 없어지게 된다.
이를 제어 위험이라고 한다.

참고로 이를 해결하기 위해 사용하는 기술 중 하나가 분기 예측이다.
분기 예측은 프로그램이 어디로 분기할지 미리 예측한 후 그 주소를 인출하는 기술이다.

-~챕터 3 : 슈퍼스칼라~-

오늘날의 대부분의 CPU에서는 여러 개의 파이프라인을 이용한다.
이처럼 CPU 내부에 여러 개의 명령어 파이프라인을 포함한 구조를 슈퍼스칼라라고 한다.

슈퍼스칼라 구조로 명령어 처리가 가능한 CPU를 슈퍼스칼라 프로세서 또는 슈퍼스칼라 CPU라고 한다.

슈퍼스칼라 프로세서는 이론적으로 파이프라인 개수에 비례하여 프로그램 처리 속도가 빨라진다. 하지만 실제로는 파이프라인 위험 등의 문제들을 직면할 수 있어 반드시 파이프라인 개수에 비례하여 처리 속도가 빨라지지는 않는다. 이 때문에 슈퍼스칼라 CPU는 파이프라인 위험을 방지하기 위해 고도로 설계되어야 한다.

-~챕터 4 : 비순차적 명령어 처리~-

오늘날 CPU 성능 향상에 큰 기여를 한 기법이자 대부분의 CPU가 차용하는 기법이다.
지금까의 파이프라이닝, 슈퍼스칼라는 순차적으로 진행되었다.
하지만 파이프라인 위험과 같은 문제들로 인해 이따금씩 명령어를 곧바로 처리하지 못하기도 하였다.
만약 모든 명령어를 순차적으로만 처리한다면 이런 예상치 못한 상황에서 명령어 파이프라인은 멈춰버리게 된다.

사진에서도 2번 명령어가 처리되기 전까지 모든 명령어가 지연되는 상황이다.
괜히 데이터 의존성도 없는 명령어들까지 피해를 보는 실정이다.

그렇기에 명령어를 순차적으로만 실행하지않고 순서를 바꿔 실행해도 무방한 명령어를 먼저 실행하여 명령어 파이프라인이 멈추는 것을 방지하는 기법, 비순차적 명령어 처리 기법을 사용한다.


데이터 의존성이 있는 3번 명령어를 순서를 바꿔 뒤늦게 실행함으로써 효율적으로 병렬 처리를 할 수 있게 되었다.

이처럼 비순차적 명령어 처리가 가능한 CPU는 명령어들이 어떤 명령어와 데이터와 의존성을 가지고 있는지, 순서를 바꿔 실행할 수 있는 명령어에는 어떤 것들이 있는지를 판단할 수 있어야 한다.

-~정리~-

오늘은 CPU 내부에서 명령어를 병렬처리하여 성능을 높히는 법을 알게되었다.

profile
"벽은 없다" - 샘 알트만

0개의 댓글