벤치리뷰·뉴스·정보/아키텍처·정보분석

[분석정보] CPU 고속화의 기본 수단 파이프라인 처리의 기본 1/2

tware 2010. 9. 6. 21:00

 

이번에는 CPU의 파이프 라인에 대해 설명을 해보고 싶다. 하지만 그 전에 디지털 회로의 기초를 조금 복습 해두고 싶다.

원래 게이트는 어떤거야?

 디지털 회로에서는 자주 Gate (게이트)라는 용어가 나온다. 게이트 라는 용어는 매우 일반적으로 사용되지만, 크게 나누어 두 가지 의미가 있다. 하나는 "문" 으로의 게이트, 예를 들면 트랜지스터 내부의 전압 제어를 하는 부분을 가리키는. "게이트 산화막" 이나 "HKMG"(High-k Metal Gate)" 이나 부르는 것이 이것 이다. "Clock Gating" 또는 "Power Gating" 도 마찬가지로, 이곳은 클럭 신호 및 전력 공급 회로의 "문으로 작용 회로"의 뜻이다.

 또 하나의 의미가 "디지털 회로의 최소 단위"의 의미이다. 디지털 회로의 최소 단위라고 말하는 논리 회로로, NOT / AND / OR 등 세 가지 연산과 0과 1 (또는 Low와 High)의 2 종류의 상태 값 논리를 설명하는 것이다. CPU는 별로 관련이 없지만 ASIC 라든지 FPGA 등에서 "게이트 어레이" 라는 "XXX 만 게이트 상당" 라는 표현을 할 때 게이트가 이것이다.

 보통은 NAND 회로 또는 NOR 회로 1개를 1게이트 라고 부르지만, 최근에는 좀 더 복잡한 것을 1 게이트 라고 표현하는 경우도 있다. 이 1 게이트를 어떤 트랜지스터에서 실현 하는가 하는 것도 이것 또한 제품에 따라 다르다. CPU처럼 회로의 최적화를 도모 한 몇 개의 트랜지스터로 실현할 수 있지만, ASIC 등 몇 개 ~ 10 개 가까이 FPGA는 잘못하면 수십 개가 필요하기도 하다. 이것은 각 제품의 특성에 따라 게이트 자체에 요구되는 요구가 다르기 때문이다.

 그러면 "게이트로 무엇을 할 수 있나?"라는 하나의 샘플이 그림 1이다. 이것은 "RS 플립 플롭"또는 "RS 래치 '등으로 불리는 것으로, 왼쪽의"Set "에 High를 넣으면 출력이 High, 왼쪽의"Reset "에 High를 넣으면 출력이 Low를 유지하는 것이다. 즉 SRAM의 1bit 분이라고 생각하면 된다.

 

 

[그림 1] 기본 게이트 구조


 RS 플립 플롭은 매우 원시적이고, 게다가 여러가지 문제도 있으므로, 일반적으로는 좀 더 복잡한 것을 사용한다. 하지만 게이트 회로 SRAM을 만들 경우 2 게이트 정도 필요할 것을 알아야 한다. 연산 회로 등도 이런 식으로 다양한 게이트를 조합하여 구성된다. 그러나 복잡한 연산을 시키려고 하면 회로가 일단(계)으로는 해결이 안되기에 그림 2와 같이 복수의 회로를 차례로 연결한 형태로 실현하게 된다.

 

 

[그림 2] 여러 회로의 조합 예


 그런데, 그림 2와 같이 복수의 회로가 연결되어 있는 경우 문제가 되는 것은 지연이다. 그림 2는 입력에 대해 "A → B → C → D '라는 4 개의 처리가 행해지지만, 여기서"D는 A의 출력과 C의 출력을 모두 필요로 한다 "라고 할 수있다 . 문제는 A / B / C 모두 입력 후 "조금"경과 한 후 출력되기 때문에 시간축으로 보면 점점 늦어진다. 거기서 문제가되는 것은 D 입력에서 A의 출력과 C의 출력 타이밍이 미묘하게 어긋나 있으므로, D가 제대로 작동하지 않을 수 있다.

 

이를 보완하기 위해 등장하는 것이 래치 회로이다 (그림 3). 래치 회로라고하는 것은 요컨대 그림 1의 SRAM 그 자체이며, "입력 된 값을 유지하고 계속"기능을 가진다. (신호를 늦춰서 맞춰주는 일종의 버퍼라고 생각하도 됩니다. 클럭이 낮을 때는 미묘한 시간차가 있어도 문제 없이 동작하지만, 클럭이 높으면 약간만 시간차가 발생해도 부정확한 결과가 나오겠죠. 버스의 폭이 32비트라고 하면, 32비트에 해당하는 각각의 신호가 정확히 동시에 와야 정확한 처리가 가능하겠죠. 1개 이상의 신호가 늦게온다면, 부정확한 처리가 되거나 에러가 나겠죠. CPU나 기타 IC의 내부를 직접 볼 수는 없고, 간단히 메인보드를 보면, CPU에서 램으로 가는 배선을 보면, 그냥 직선으로 되어 있는게 아니라, 어떤 선은 중간중간 꺾이는 부분을 빼면 최대한 직선으로 되어 있는 배선이 있고, 어떤 배선은 크게 꺾이는 것 포함해서 직선으로 쭉 가다가 갑자기 좌우로 매우 짧은 지그재그로 배선이 되어 있는걸 볼 수 있어요. 이건 각 배선의 길이를 맞추기 위해서 이렇게 되어 있는 겁니다. 배선의 길이가 같아야 정확히 처리가 가능하니까요. 다르게 말하면 메모리 오버클럭이 더 잘되는 보드가 있다면, 오버 옵션(타이밍 조절이 더 자세하다던가, 전압 설정이 다양하다던가)이 물론 중요하지만, 이런 배선의 길이가 얼마나 더욱 정확한가에 따라서 오버가 더 잘 되냐 안되냐가 생깁니다. 아주아주 미세한 차이는 클럭이 낮을 때는 문제가 없지만, 클럭이 높아아지면, 상대적으로 차이가 더 벌어져서 에러가 나니까요. PCI-EX 슬롯의 경우는 직렬 버스이기 때문에 (병렬버스가 좌우로 한조가 되어서 동시에 데이터를 전송 한다면, 직렬 버스는 각자 줄마다 앞뒤로 한조가 되어서 전송), 1배속(레인)에서 4배속 16배속으로 늘어도 각 레인별로 선을 동일하게 맞추지 않아도 됩니다. 다만 1배속 내의 신호선 자체가 차동신호로 전송하는데, 이 2개의 신호선은 정확하게 같아야 합니다. (1레인 안에 상향 두선, 하향 두선, 각각의 두선은 동일한 길어어야 함).

 

[그림 3] 그림 2 래치 회로를 가한 상태


 앞의 예의 경우라면 D에 입력되는 두 신호 래치를 사이에 두는 것으로, 두 신호가 같은 타이밍으로 출력되게 된다. 이 타이밍을 결정하는데 사용 된 것이 이른바 클록 신호이다. 즉 CPU의 동작 주파수 라든지 말해지고 있는 것은 사실 내부 래치의 동작 타이밍을 결정하는 것이다.


 "동작 주파수를 높이면 그만큼 트랜지스터가 고속으로 움직이는"라고 착각하고 있는 (실제로 래치 회로의 내부 관해서는 이렇게지만) 사람도 있을지도 모르지만, 그림 3에서 말하면, A ~ D의 회로에 클럭 신호가 공급되지 않는다. 이러한 회로 내부의 게이트 회로와 그 안의 트랜지스터는 클럭 신호와는 무관하게 동작한다.

 이런 식으로 여러 회로 사이에 래치 회로를 사이에 두고 거기에 외부 클록 신호를 넣는 방식을 일반적으로 "동기화 회로" 라고 부른다. 결국 래치 회로는 클록의 타이밍에 동기하여 동작을 진행하기 때문이다.

 동기화 회로가 있으면 물론 "비동기 회로"도 있다. 이곳은 래치를 생략 형태로 구현한다. 다 꺼내 말하면 자리수 이야기, CPU의 소비 전력의 큰 부분은 래치 회로가 차지하고 있으며,이를 빼는 경우 상당한 전력 절감이 가능해진다. 또한 [그림 2]와 [그림 3]을 비교하면 알 수 있듯이 래치 회로는 기능은 "신호를 지연 시키는"것이며,​​ 이것은 넓은 의미에서 성능 저하의 요소가 된다.

 그럼에도 불구하고 비동기 회로에서 제조된 CPU 라고 하는 것은, x86에서는 전무하며, 더 넓은 범위에서 봐도 ARM과 맨체스터 대학이 공동으로 연구 개발을 했던 "Amulet" 시리즈와 Philips (현 NXP Semiconductor)의 사업 회사였던 Handshake Solutions 사의 "ARM996HS" 정도만. 제품화 된 것으로 필자가 유일하게 알고있는 것은 샤프의 "DDMP"(Data-Driven Media Processor) 정도 밖에 없다.

 왜냐하면 간단한 이야기​​로, 래치 없이 타이밍 설계가 매우 어려워지기 때문이다. 실제로 100 게이트 정도의 회로에도 래치없이 설계하는 것은 매우 어렵다. 10000 게이트를 초과하면 CAD 등에서도 꽤 디자인은 어려울 것이다. 타이밍의 차이 방법은 고유하게 정해지는 것은 아니다. 특히 요즘 같이, 프로세스의 미세화에 수반하여 트랜지스터의 동작 특성의 편차가 커지고 있는 상황에서 상당한 여유를 많이 가지지 않으면 제대로 움직이는 것은 만들 수 없다. 그렇게 되면 오히려 래치를 넣은 것이 안정되고 디자인도 훨씬 간단하기 때문이다.

 

 

파이프 라인의 기본
스테이지마다 차례 차례로 처리하는


 이상의 기초 지식을 밟아 좀 더 CPU 내부의 이야기를 한다. 일반적으로 CPU의 경우 수행 할 작업은 다음 5단계 (스테이지라고 부른다)로 구성된다.

Fetch
다음 처리해야 할 명령어를 메모리나 캐시로부터 취득한다.

 

Decode
취득한 명령을 해석하고 어떤 작업을 수행해야 하는가를 결정한다.

 

Data Fetch
필요하다면 처리에 필요한 데이터를 채 웁니다.

 

Execute
처리한다.

 

Writeback
처리 결과를 출력.

 

 오래된 CPU는 Decode와 Data Fetch가 함께 되어 4단계 라든지, Execute와 Writeback을 함께하고 3단계 라든지, Fetch와 Decode도 함께해 2단계 라든지, 얼마든지 쉽게 할 수 있지만, 기능 분할을 하면 대개 이 5 단계가 된다.

 그리고 이들을 구현하는 경우, 내부 회로는 대략적으로 [그림 4]와 같이된다. 위의 다섯 단계는 각각 여러 회로를 연결하는 형태로 구현되어 있다. 기본적으로는 Writeback의 최종 처리가 끝나면 그것을 트리거에 다음 명령어 Fetch을 시작하는 구조이다.

 

 

[그림 4] 기본적인 CPU의 스테이지 구성


 그리고 [그림 4]의 경우에서 어떻게 명령이 처리되어 가는지를 나타낸 것이 [그림 5]이다. 여기에서는 우선 5 개의 스테이지가 모두 같은 시간에 처리 할 수​​ 있다는 전제로하고 있지만, 만일 1 단계 1 클럭에 처리 할 경우에도 1 명령어 당 5 클럭을 필요로 하게 된다. 그림과 같이 4명령 실행 경우 20 클럭 필요한 셈이다.

 

[그림 5] 명령 처리 흐름


 이것을 "좀 더 빠르게 할 수 없을까? "하는 것으로 생각 된 것이, 파이프 라인이다. 기본적인 구조는 변하지 않지만, 지금까지는 "Writeback의 출력이 끝나면 다음 Fetch 시작"였던 것이 "각 단계마다 작업이 끝나면 다음 명령을 처리하기" 형태로 변경되고 있다.

 

 

[그림 6] 파이프 라인 된 스테이지


 이렇게 하면 처리의 진행 방법은 그림 7과 같이된다.

 

 

[그림 7] 파이프 라인에서 명령 처리 흐름

 


 각 단계에 걸리는 시간은 변하지 않지만 각 스테이지가 항상 처리를 행하고 있기 때문에 실질적인 처리 능력 (이 그림의 경우) 5 배가 되고 있는 셈이다. 이런 식으로 항상 CPU의 내부 회로 전체가 작동하도록 한 것이 파이프 라인으로 불리는 고속 수법이다.

 

이것을 더 빠르게 하고자 하는 경우에는 전체 파이프 라인의 단계를 세분화 할 수 있다. [그림 6]은 각 스테이지가 3 개의 회로로 구성되어 있었지만, 이것을 전부 뿔뿔이 흩어지게 해 잘게 래치를 넣은 그림 8과 같이 회로를 구성하면 동작 주파수를 더욱 가속화 할 수있다 (그림 9).

 

 

그림 8 더욱 세분화 한 스테이지

 

 

[그림 9] 그림 8에서 명령 처리 흐름


 이것 이라면 각각의 처리로 인한 지연은 더 적기 때문에, 래치의 타이밍을 더 빨리해도 충분히 쓸 수 있다. 그만큼 클럭 속도를 끌어 올릴 수 있다는 것이다. 이러한 세분화 된 파이프 라인 구조를 "Super Pipelinging"(슈퍼 파이프 라이닝) 또는 "Hyper Pipelining"라고 부른다 (하이퍼 쓰레딩과 관계 없음. 깊은(긴, 단계가 많은) 파이프 라인의 호칭. 현대 CPU에서 파이프라인은 무조건 기본이고 (길던, 아주 길던, 짧던), 지금도 정말 간단한(초초 저성능,저전력) CPU가 아니라면, 파이프라인이 여러개인 (수가 많은) 슈퍼스칼라 역시 기본인데, 이 슈퍼 스칼라 구조 위에서 2개의 스레드를(태스크를) 동시에 실행 가능한 것이 하이퍼 스레딩. 더 높은 성능을 위해서는 슈퍼스칼라 + 아웃 오브 오더 + 명령변환 + 하이퍼스레딩.).


 그렇지만, 이러한 파이프 라인의 (단계,깊이) 증가는 두 가지 단점이 있다.

 

하나는 파이프 라인의 스톨과 파이프 라인 해저드 등 예상치 못한 사태로 인해 파이프 라인이 정지하거나 다시하게 되거나 하는 경우 그 영향이 매우 큰 것이다.

또 하나는 래치의 수 자체가 크게 늘어난 데 따른 소비 전력의 증대이다.

 

Pentium 4 Netburst Architecture의 경우, 전자는 설계 단계에서 상정되고 있어 이를 보완 하기 위한 구조가 준비되어 있었지만, 후자에 대한 준비는 싱거웠다. 이것이 결과적으로 소비 전력의 증대나 과도한 발열로 이어져 궁극적으로 제품 수명을 단축하게 되어 버렸다.(훨씬 더 길게 본 아키텍처지만 다 취소되고 콘로로 대체. 기본 20단계 였던 윌라멧,노스우드를 31단계로 늘린 프레스컷의 경우 더욱 성능 하락을 대비한 설계가 적용.아래 프레스캇 링크 글과 파이프라인 2/2를 참고.

 

그렇다고 파이프 라인 단계를 줄이고 (클럭을 낮추고), 무작정 IPC를 높이려고 파이프 라인 수 자체를 늘리는 (슈퍼 스칼라 + 아웃 오브 오더 + 명령변화) 것도 문제가 생깁니다.

 

최대 명령 병렬화 실행이 어렵기 때문이죠 (즉 회로당, 다이크이당 성능이 비효율적이 됨. 이로 인해서 또 다시 하이퍼스레딩(SMT)가 추가 됩니다만.. IPC 높은 CPU 코어로 최대 IPC를 확보하면서, 항상 최대 명령 병렬 실행을 못하는 부분은 동시 스레드 실행으로 코어내 최대 명령 병렬 실행 확보).

 

즉 적절하게 IPC와 클럭속도를 잘 균형잡아 설계해야 최적의 성능을 가진 CPU가 나오게 됩니다. (CPU의 성능은 = 클럭 x IPC (멀티코어는 x 코어수) 이기 때문에 클럭이 낮아도 IPC가 매우 높아서 100 이라는 성능을 낼 수도 있고, IPC는 낮지만 클럭이 매우 높아서 100 이라는 성능을 내도록 만들 수 있겠죠. 그런데 한쪽으로 치우치면 좋지가 않죠. 각각이 모두 장점과 단점이 있기 때문에요.) 다만 여기서는 설명을 위해서 단순히(다른 기사에서도 마찬가지)  CPU 코어수 x  성능이라고 하지만, 실제로는 코어수만큼의 배수로 성능이 증가하지는 않습니다. 같은 CPU가 2코어가 되어도 (버스, 공유 라스트 캐시(L2 또는 L3) 등 까지 2배가 되어도) 실제 성능은 2배가 되지 못합니다. 하드웨어적인 측면도 그렇고,  소프트웨어 측면에서도 완벽하게 병렬화 된 프로그램밍이 불가능하기에 더욱  성능이 2배가 안되죠. 아주 복잡하고 다양한 연산을 해야 할 때나 각각의 코어에 나눠서 연산을 할 수 있지 (이것도 모아서 최종 결과를 낼 때도 병렬화가 불가능 할테구요) 아주 간단한 연산을 2코어로 나눠서 할 수가 없죠. 할 수 있다고 해도 1코어로 하는게 더 낫겠죠. 그렇기 때문에 단순히 기존 아키텍처를 (그대로, 또는 약간 개선판에) 코어수만 늘려서 나오는게 아닌, IPC가 더 높은 새로운 아키텍처를 개발하는 겁니다. 그러면서 코어수도 점차 늘려가는 것이죠.)

 

[고전 2003.02.20] Intel 차세대 CPU Prescott의 정체를 밝혀

 

 라는 것으로 다음은 파이프 라인의 문제점과 대책을 설명 하고자 한다.

 

 

 

 

 

[분석정보] CPU 고속화의 기본 수단 파이프라인 처리의 기본 2/2

 

 

[분석정보] 슈퍼 스칼라에 의한 고속화와 x86의 문제점은

 

 

[분석정보] 명령의 실행 순서를 바꿔 고속화 하는 아웃 오브 오

 

 

[분석정보] x86을 고속화하는 조커기술 명령변환 구조

 

 

[분석정보] CPU와 메모리의 속도 차이를 해소하는 캐시의 기초지식

 

 

[분석정보] 캐쉬 구현 방식으로 보는 AMD와 인텔이 처한 상황

 

 

[고전 2005.11.30] 마이크로 아키텍처의 변화를 반영하는 "Core"브랜딩

 

 

[분석정보] 20년 후인 지금도 곳곳에서 살아남은 펜티엄 아키텍처

 

 

[분석정보] 5W 이하의 저전력 프로세서의 개발로 향하는 Intel

 

 

[분석정보] intel의 듀얼 코어 CPU 1번타자 Montecito

 

 

[분석정보] 멀티 코어 + 멀티 스레드 + 동적 스케줄링으로 향하는 IA-64

 

 

[고전 2002.10.04] Pentium 8 후보 Nehalem 아키텍처

 

 

[정보분석] Penryn의 1.5 배 CPU 코어를 가지는 차세대 CPU "Nehalem"

 

 

[고전 2002.09.12] Hyper-Threading Technology를 지원하는 HTT Pentium 4 3.06GHz