Author : Daeguen Lee

(Any action violating either copyright laws or CCL policy is strictly prohibited)

(※ 이 글은 월간 smart PC사랑 2011년 11월호에도 수록되었습니다.)

 

 

 

 

안녕하세요. 오랜만에 글다운 글(?)로 찾아뵙게 되어 반갑습니다.
1~2주 전쯤 불도저란 이름으로 알려졌던 AMD FX-8150P, 코드네임 Zambezi를 입수해 테스트를 해 왔습니다.
그 동안 AMD에서 유출(?)된, 아키텍처에 관한 기술적인 자료들과 직접 테스트한 결과를 함께 종합해 보며
오늘 제가 작성할 리뷰는 작년에 올렸던 '현대 CPU의 구조' 강좌부터 짚고 넘어가야겠단 계획을 세웠습니다.
(그 글에서 최초로 불도저의 성능을 예견했기에, 이젠 되짚어보며 맞고 틀린 부분을 검증해 보고 싶었거든요)

프로세서의 성능을 결정짓는 요소들은 사실 그 프로세서의 아키텍처를 떼놓고는 생각할 수 없는 것들입니다.
작동 속도, 캐시의 용량, 관리 정책 등 모든 요소에 설계 당시의 철학이 녹아 있다고 보아도 과언이 아닌데,
일례로 '경쟁사보다 높은 작동 속도'를 추구하며 개발 단계에서부터 아키텍처의 폐기에 이르기까지
시종일관 '가늘고 깊은' 파이프라인을 고수했던 넷버스트 아키텍처를 떠올려 볼 수 있겠습니다.

인텔은 넷버스트 이후 프로세서 개발의 기조를 변경, '넓고 얕은' 파이프라인을 구현하는 쪽으로 선회했는데
그 결실인 '코어' 아키텍처가 현재까지의 인텔 CPU 구조의 근간을 형성하고 있다고 해도 과언이 아닙니다.
(이후 등장한 네할렘 / 웨스트미어 / 샌디 브릿지에 이르기까지, 근본적인 구조는 크게 다르지 않습니다)

아무튼. 여기까지의 내용들은 지난 강좌들을 다시 한번 복습해 주시기 바랍니다.
(※ 링크는 새 창에서 열립니다)

- 현대 CPU의 구조: 1편 (백엔드 편)
- 현대 CPU의 구조: 2편 (프론트엔드 편)
- 현대 CPU의 구조: 3편 (메모리 계층 구조와 성능)

아울러 외전 격인 아래의 세 글도 읽고 오시는 것을 권해 드립니다.

- 오버클럭의 공학적 배경
- 멀티스레딩 기술의 이해
- 파이프라이닝의 이해

그럼, 이제부터 지난 1/2편의 마지막 파트에 소개했던 불도저 아키텍처에 관해 복습해 봅시다.

.
.
.

 

 


▲ ...불도저를 보자더니 왜 이미 본 그림을 또 보여주냐! 고 하시면 할 말 없지만...^^;;
이 그림에 나타난 구조. 이젠 익숙하신가요?
자, 그럼 바로 본론으로 들어갑니다!

.
.
.


▲ 예전 강좌에서 소개했던 불도저의 프론트엔드 구조입니다.
(terminology는 앞으로 이 글에서 다루지 않겠습니다. 이전 강좌들을 읽고 오세요...^^)
펜티엄 4의 넷버스트 아키텍처가 그랬듯, 프론트엔드 내부에 트레이스 캐시를 탑재한다는 루머가 있었지만
출시가 임박한 지금까지 AMD의 기술 문서를 죄다 뒤져보았지만 관련 내용이 없는 것으로 보아
위에 그려 두었던 트레이스 캐시 관련 내용은 사실이 아닐 것으로 보입니다.

또한 인텔의 코어 아키텍처에서 도입되었던 루프 탐지기 (LSD) 역시 불도저에 도입된다는 루머가 있었는데
이 역시, AMD의 기술 문서에 소개되지 않은 것으로 보아 사실이 아닐 가능성이 높습니다.
(명확히 "아니다" 란 이야기를 보지 못했기에 일말의 여지를 열어 둡니다만... 99.9% '아닐 겁니다.')

이 두 컴포넌트가 어떤 기능을 수행하는지, 있었으면 어떻게 좋았을지... 는 이전 강좌를 읽어 주세요 ^^;

아무튼. 그리하여 최종적인 (실제의) 불도저의 프론트엔드 구조는 아래와 같습니다.


▲ 뒤에서 다시 이야기하겠지만, 불도저는 '2 코어'로 간주되는 덩어리가 하나의 '모듈'이란 단위를 구성하는데
프론트엔드는 모듈 차원에서 공유되므로 사실상 1코어분으로 보아도 큰 무리가 없습니다.
이러한 '1코어 어치'의 프론트엔드가 스레드 수준에서의 병렬성 (TLP) 을 확보하기 위한 방법으로
인텔의 하이퍼스레딩과 비슷하게, 프론트엔드의 Architectural state가 복제되어 있을 것으로 여겨집니다.

(※ Architectural state는 위 그림(및 제 강좌 전체)에는 등장하지 않는데, 그 이유는 저는 지난 강좌에서
프론트엔드를 구성하는 여러 단계 중에서도 디코더와 그 전후 단계를 중심으로 다루었기 때문입니다.)

Architectural state란 컨트롤 레지스터(CR)와 범용 레지스터(GPR)을 묶어 이르는 말로,
간단히 두 개의 스레드를 감독하는 '창' (window) 이라 생각하시면 될 것 같습니다.

아무튼. 불도저의 프론트엔드는 (이것을 1코어분으로 볼 경우) 그간의 K8~K10과 비교해 꽤 거대해졌는데
디코더는 33.3% 늘었고 ROB 용량이 무려 80% 가량 증가해 이를 바탕으로 큰 성능향상을 예측한 바 있습니다.
(아직 백엔드 얘긴 꺼내지도 않았지만... 프론트엔드의 성능이 프로세서 성능에 큰 영향을 미치기 떄문입니다)

이러한 불도저의 프론트엔드에 한 개의 스레드만 들어올 경우, 그 스레드가 거치는 경로는 아래와 같습니다.


▲ 달라진 부분을 아시겠나요?
앞서 그렸던 프론트엔드에는 두 개의 16바이트 페치 버퍼가 존재했지만,
하나의 스레드는 하나의 페치 버퍼만을 경유하므로 한 개의 16바이트 페치 버퍼를 상대하는 셈이 됩니다.
또한 ROB로부터 백엔드로 이슈 가능한 최대 명령어 수는 (원래는) 각 정수 코어와 FPU에 4매크로옵씩으로
총 12매크로옵이 되지만, 하나의 스레드만 처리할 경우 두번째 정수 코어는 관여하지 않으므로 이 경우엔
최대 8매크로옵에 해당하는 대역폭이 확보되는 셈입니다. (= 2/3로 감소)

그럼... 이제 백엔드 구조를 살펴봅시다. 우선 지난 강좌에서 예측했던 구조부터 보도록 하죠.


▲ 지난 강좌를 작성할 당시, 모듈 단위로 공유되는 FPU에 3개의 128bit 유닛이 있다고 생각했었지만
최종적으로 공개된 기술 문서를 보니 128bit 유닛은 2개이고 나머지 둘은 정수 벡터 유닛이더군요.
...하여, 다시 그린 그림은 아래와 같습니다.


▲ 이전의 그림과 비교했을 때 성능상 달라질 부분은
- 128bit 벡터 명령어 (= SSE) 처리 속도 33.3% 감소
- 256bit 벡터 명령어 (= AVX) 처리 속도 33.3% 감소
정도 되겠습니다. 그렇더라도 최대 12개의 마이크로옵을 처리 가능한 백엔드 대역폭은 꽤나 넓은 편입니다.
(물론 '넓다'는 비교 기준은 위 그림을 1코어분으로 생각했을 때의 얘기입니다.)

또한 눈썰미가 좋으신 분은 달라진 표기를 또 하나 눈치채셨을 텐데... 바로 FMAC 라는 이름입니다.
AMD와 인텔이 함께 개발한 AVX ISA는 256bit 벡터 지원 외에도 Fused Multiply-Add 란 기능이 추가되었는데,
이것은 간단히 말해 덧셈과 곱셈이 혼합된 연산 (= 피연산자가 3개인) 을 한 사이클에 수행하는 명령어입니다.

예를 들어 (a+b)*c=d 라는 연산을 수행해야 한다고 가정해 봅시다.
기존의 2피연산자 명령어는 덧셈/곱셈/쓰기 등 각 연산을 단계별로 분리해 수행할 수밖에 없지만
3피연산자 명령어 형식이 지원될 경우 전체 연산에 필요한 사이클이 획기적으로 줄어듭니다.

불도저에는 이러한 (3피연산자 지원) AVX 외에도, 4피연산자를 지원하는 FMA4라는 ISA가 추가되어 있습니다.
(FMA4의 잠재력에 대해서는 이 리뷰의 뒤쪽 파트에서 다루도록 하겠습니다.)

그럼... 이번에는, 1개의 스레드가 점유할 수 있는 백엔드의 자원을 보도록 하겠습니다.


▲ 이전의 백엔드 강좌에서 K8~K10.5 아키텍처를 보고 오시면 좀 더 확연한 비교가 가능하실 것 같습니다.
Rough하게 말하자면 정수/부동소수점 유닛 모두 K8~K10.5 대비 2/3 수준으로 줄어들어 있습니다.
유일하게 확장된 부분이라면 (FPU 부분의) 벡터 유닛이 하나 더 늘었다는 것과
FPU 부분에 이슈 가능한 포트가 한개 더 늘어 33.3% 정도의 향상이 있을지도 모른다는 점입니다.
(즉, 굳이 양분해 말하자면 불도저는 정수 성능보다는 부동소수점 성능에 더 비중을 둔 아키텍처입니다)

또한 불도저는 고클럭화를 위해 "파이프라인 스테이지당 게이트 수(=트랜지스터 수)를 줄였다" 고 밝혀졌는데,
곧 (고클럭을 위해) 파이프라인 스테이지를 늘렸다는 것으로, 이는 과거 넷버스트의 설계 이념과 비슷합니다.
또한 이것이 사실일 경우 정수 보다 부동소수점 성능에 치중한 불도저의 아키텍처를 이해할 수 있게 되는데
깊은 파이프라인 구조에서 성능 저하가 심한 정수 연산과 달리, 부동소수점 연산은 분기 예측에 따른 리스크가
상대적으로 적은 만큼 파이프라인을 심화시켜 클럭을 높이면 거의 그에 비례해 성능이 오르기 때문입니다.

또한 인텔은 넷버스트를 도입하면서 낮은 정수 성능을 보완하기 위해 2배속 정수 유닛을 탑재한 바 있는데
불도저도 그러한 철학의 연장선에서, 정수 성능의 저하를 막기 위해 정수 유닛을 두배 늘린 것으로 보입니다.
이렇게 보니 넷버스트 아키텍처와도 상당히 유사해 보이죠?

문제는, 깊은 파이프라인 설계에서 클럭당 성능의 하락은 불가피해진다는 점입니다.
(이전 강좌를 작성할 당시엔 K10.5 까지의 구조를 준용해 생각했기에 당시의 예상은 빗나갈 수 있겠습니다.)

...아무튼. 지금까지의 그림을 바탕으로 우리가 맨 처음 보았던 '큰 그림'을 다시 그려 보면 아래와 같습니다.


▲ 이것이 불도저 '2코어' 입니다.
이쯤 되면 코어 단위를 가리키는 말에 어폐가 느껴질만 한데...
예를 들어 AMD의 Phenom II X6은, 위 그림을 사용해 만들어 보면 아래와 같은 구조가 됩니다.


▲ 의심할 여지 없이 '6코어' 구조가 확실합니다.
반면, 조만간 출시될 AMD FX "Zambezi" 8코어 프로세서의 다이 구조는 아래와 같습니다.


▲ ...흐음............

단지 백엔드에 정수 유닛을 보충한 것만으로 하나의 모듈이 2코어분의 역할을 해낼지 궁금해지는데,
다음 파트에서 이어질 각종 테스트 결과를 통해 한번 검증해 보도록 합시다.

제가 지난 강좌들로 예측했던 불도저의 '총 성능'과 '싱글스레드 성능'이
실제 벤치 결과를 통해 어느 정도 증명되었는지 or 반증되었는지 눈여겨 봐 주시기 바랍니다.

그럼, just enjoy!