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

[분석정보] AMD의 신 GPU 아키텍처 "Graphics Core Next"의 비밀

tware 2012. 2. 1. 16:00


방향이 갖춰진 NVIDIA와 AMD의 GPU 아키텍처


 AMD의 신 GPU "Radeon HD 7900 (Tahiti : 타히티)"는 Radeon HD 2000 (R6xx) 계 이후, 5년만에 프로세서 아키텍처를 일신했다. 새로운 아키텍처는 단순히 "GCN (Graphics Core Next)"라고 부른다. AMD의 GCN 아키텍처는 프로세서의 기본 구조만 보면 NVIDIA의 GeForce GTX 4/5 (Fermi : 페르미)나 Intel의 Larrabee (현재는 Knights 시리즈)와 비슷하다. 모두 16레인 벡터 유닛을 갖추고 있으며, 프레디케이션에 의한 제어 흐름 제어가 가능하다.

 벡터 유닛의 기본 구조가 공통화 됐다는 것은, 3사의 벡터 프로세싱으로의 발맞춤이, 부분적이기는 하지만 모여진 것이다. 다만, Intel은 PC 급 제품에는 기존의 내장 GPU 코어를 발전시킨 코어를 제공하고 있어, 구조가 분단되어 있다.

 Tahiti (Radeon HD 7900)의 구조는, 각 프로세싱 클러스터 내부와 GPU 전체 구조의 모두 NVIDIA의 Fermi와 비슷하다. 프로세싱 클러스터 내부에는, 16레인 벡터 유닛이 복수 구현되어, GPU 전체는 다수의 프로세싱 클러스터로 분할되어 있다. 각 클러스터는 개별적으로 동작하고, 메모리는 쌍방향 크로스바 스위치와 읽기와 쓰기가 가능한 캐시 계층으로 묶여있다. 아래는 Tahiti의 전체 그림과 Fermi의 GF100 / GF110의 전체 그림이다.

 

Tahiti의 전체도

 

 

 

GF100 / 110의 전체도

 


 Tahiti와 Fermi가 비슷하다는 것은 우연이 아니다. 또한 AMD가 흉내를 냈다는 얘기도 아니다. GPU 아키텍처를 범용 컴퓨팅을 위해 최적화하면 자연스럽게 비슷한 방법으로 도착 한다는 얘기다. 또, 양사의 아키텍처는 여전히 큰 차이가 몇가지 있어, 그것은 설계 사상의 차이를 반영하고 있다.

 다만 큰 틀에서는 AMD도 범용 컴퓨팅으로 GPU 설계를 최적화하기 시작한 것은 확실하다. 지금까지는 범용 컴퓨팅으로의 최적화를 빠른 속도로 계속한 NVIDIA와 그래픽으로의 최적화에 고집한 AMD는 두드러진 차이가 있었다. 그러나 이후로는 같은 씨름판에서의 싸움이 된다 (기존 AMD(ATI)의 그래픽 아키텍처는 하드웨어 구성에 비해서 (이론적 성능) 실제 성능이 안나오는 구조 입니다. (드라이버 등) 최적화의 시간이 더 오래 걸리구요. GCN부터는 좀더 쉽고 빠르게 이론적 성능에 가깝게 낼 수 있구요. 그러니까 몇년 지나서 뭔 드라이버 다 갈아서 성능이 좋아졌다 이런게 나오는 겁니다. 또 한편으로는 그만큼 능력이 없어서? 투자를 안해서 그럴 수 있구요. 처음부터 드라이버 방식이 잘못 된다던다 말이죠. 기존 하드웨어 방식의 최적화가 오래 걸린다고 해도, 좀더 오래걸린다는 것이지.... 수년동안 최적화 해야 된다는 얘기는 아니죠.

 

어짜피 하드웨어 성능은 고정되어 있고, 그걸 뛰어넘는건 당연히 불가능 한 것이고, 계속 저성능으로 쓰다가 어느순간 제성능 내는 드라이버가 나온거죠. 물론 큰 노력이 별로 없고, 그 상태 그대로 인거 보다는 낫지만, 왜 이걸 매우 좋게 생각하는지 모르겠네요 (갑자기 몇십% 증가면  그동안 드라이버를 발로 만들었다는 얘기 입니다. 하드웨어를 제어하면서 성능을 최대한 잘 쓰게 만드는게 드라이버이지, 하드웨어 성능을 초월하게 만드는게 드라이버가 아닙니다. 초월은 애초에 할 수가 없어요. CPU 오버클럭 같은게 아니기 때문이죠. 자동차 엔진 튜닝해서 엔진 성능을 증가 시킨다 이런게 아니기 때문이죠.)

 

처음부터 어느정도 제 성능을 내고 (처음부터 최대 성능 내는 드라이버를 만들기도 힘들고, 또 게임은 계속 나오니까), 조금씩 조금씩 기존에 미진했던 부분의 최적화 되어서 조금씩 성능이 증가되는 엔비디아 쪽이 훨씬 좋은건데요. 같은 것으로 예전 인텔 내장 그래픽이 (GMA 시절. 그래픽 미디어 액셀레이터) 엄청나게 욕먹는게 AMD와 같은 이유였죠. 내장이니까 애초에 성능이 낮은 것도 있지만, 그 성능 조차 제대로 못 쓰는 감속기 (이름처럼 엑셀레이터가 아닌) 드라이버라고요. 이것도 AMD처럼 대대적으로 홍보를 안해서 그렇지, 시간이 지나서는 성능 증가가 있고, 호환성 부분도 해결이 되어갔지만, 그 때문에 욕먹었죠. 처음부터 제대로 만들지.. 라고... 그러나 같은 AMD에게는  뭔가 사용자에게 어마어마한 은혜를 준것 같이 얘기하는 사람이 태반... 같은 건데 왜 평가가 다를까.... 조중동 보는 느낌..... 또 이거 외에는 AMD 카드가 겉으로 드러난 스펙이 엔비디아 카드보다 높은 경우 게임에서 엔비디아에 비해서 성능이 저조하면, 이걸 게임사와 엔비디아 탓으로 돌린다거나...... 존 카멕도 13류 프로그래머로 만든다거나... 특히나 AMD 카드들이 원래 OpenGL 성능이 낮은 것도 게임 개발사 탓으로 돌린다거나. 다이렉트x는 그래도 그럭저럭 성능이 나오는데, OpenGL이 이런거면 OpenGL 쪽은 드라이버를 정말로 발로 만들었다는 얘기 입니다... 

 

같은 AMD 제품이면서  세부적인 SP 숫자나 ROP, 텍스처 유닛 숫자가 동일한데도 아키텍처 세대가 다른 제품끼리 비교해도 새로운 제품이 성능이 훨씬 좋죠. 실제 성능이 훨씬 좋은 아키텍처이기 때문 입니다. CPU 같은 쪽도 마찬가지구요. 양사의 CPU가 같은 SSE 시리즈를 지원한다 그런데 SSE 시리즈를 적극적으로 쓰는 연산 프로그램을 돌리면 성능차가 나타난다 라면, SSE 유닛이나 기타 주변 기능들의 성능이 더 좋아서 좋은 겁니다. SSE 시리즈 명령을 처리 할 수 있는가와  얼마나 빠르게 처리하는가는 다른 얘기 입니다. x86 명령도 마찬가지 이구요. CPU든 GPU든 크게 보면 그냥 성능이 좋아서 좋은 겁니다. GPU는 이외에 드라이버를 얼마나 잘 만들었는가도 있겠지만요. 또 특정 게임에 한하면  게임 개발사가  엔비디아나 AMD에 그래픽 관련 기술 지원을 요청할 때 얼마나 잘 지원을 해줬냐에 따라서도 다를 수 있겠구요.).

 또 NVIDIA와 AMD의 GPU의 성격이나 행동이 향후 어느정도 비슷한 것이 되어가는 것도  의미한다. GPU를 범용으로 쓰는 헤테로지니어스 (Heterogeneous : 이종혼합) 컴퓨팅으로의 길이 또 한발 나아간다.



중앙화 되었던 명령 유닛을 각 프로세서 클러스터로 분산


 Tahiti (Radeon HD 7900)의 전체 구조를 보면 기존의 AMD GPU 사이에 큰 단절이 있다는 것을 깨닫는다. 아래의 그림은 AMD의 구세대 Radeon HD 6970 (Cayman)의 전체 그림이다. Cayman의 그림 중에서 크게 눈에 띄는 것은 Cayman에서는 각 프로세서에 대한 명령을 발행하는 디스패치 유닛이다. 그림 속에서 금색으로 되어있는 부분으로 AMD는 "Ultra-Threaded Dispatch Processor" 라고 불렀다.

 

Cayman의 전체도

 


 Cayman은 실질적으로 듀얼 코어 GPU로, 2계통의 그래픽 엔진과 쉐이더 코어 군을 가지고 있다. 따라서 명령 디스패치 유닛도 2 계통으로 나뉘어져 있으며, 2개의 명령 유닛 각각이 12개의 프로세서 클러스터인 SIMD 엔진에 명령을 발행했다. 각 SIMD 엔진마다 명령 시퀀서가 2계열 있어, 교대로 명령 발행을 하고 있었기 때문에, 1 명령 유닛마다 총 24개의 명령 시퀀서가 유지되고 있다. 2개로 나뉘어져 있지만, 중앙의 명령 유닛이 각 SIMD 엔진을 제어하는​​ 집중 제어 방식이다.

 

 반면 Tahiti의 전체 그림에는 기존의 중앙 명령 유닛이 보이지 않는다. 워크 디스트리뷰터가 각 엔진에 대한 작업 분배를 하지만, 실제 명령의 핸들링은 중앙 제어는 아닌 것이다. 명령 처리 기능은 Tahiti (Radeon HD 7900)에서는 프로세서 클러스터인 "컴퓨트 유닛 (Compute Unit : CU)"으로 분리되었다.

 간단히 말하면 Cayman까지의 AMD GPU는 중앙명령 유닛이 프로세서를 제어하는​​ 중앙 관제 방식, Tahiti는 각 프로세서의 명령 유닛이 독립적으로 명령 제어하는​​ 분산 방식이다. 명령의 발행이나 스케줄링 등의 제어는 클러스터 단위로 제어되며, 중앙은 작업을 할당하는 정도이다. 이 변경은 Tahiti에서 프로세서의 설계 사상의 변경과 크게 관련되어 있다.

 

 

NVIDIA의 SM에 비슷한 GCN의 CU (Compute Unit)의 구조


 AMD가 Tahiti에서 채용한 GCN 아키텍처에서, GPU는 "컴퓨트 유닛 (Compute Unit : CU)"이라 ​부르는 프로세서 클러스터로 구성된다. 컴퓨트 유닛은 연산 유닛, 로드 / 스토어 & 텍스처 유닛, 캐시 및 로컬 스크래치 패드 메모리, 명령 유닛을 갖춘 풀 프로세서이다. 아래의 그림은 CU (Compute Unit)의 전체다.

 

CU의 전체도

 

 여기서 재미있는 것은, Tahiti의 CU (Compute Unit)가 NVIDIA의 Fermi 아키텍처의 프로세서 클러스터인 SM (Streaming Multiprocessor)과 비슷한 것이다. 아래는 Fermi의 GeForce GTX 560 Ti (GF114) 계의 SM 블록도다. 모두 16레인 벡터 유닛을 복수 갖추고, 명령 유닛에서 복수의 스레드 명령을 동시에 발행한다. 기본 구조는 아주 비슷하다.

 

GF104의 SM

 


 기존의 AMD GPU에서 중앙에 있던 명령 유닛은, GCN에서는 CU (Compute Unit)로, CU에 갖추고 있다. 명령의 흐름을 쫓으면, 우선 그림의 가장 위의 명령어 페치 중재 유닛 (Instruction Fetch Arbitration)이 4개의 CU에서 공유하는 L1 명령 캐시로부터 명령어를 페치한다.

 다음으로 페치한 명령을 네개의 명령어 버퍼에 배분한다. 그림 중에서 "SIMDx Program Counter & Instruction Buffer"라 되어있는 4유닛이 그것이다. AMD GPU에서는 Wavefront 라고 부르는 64 스레드의 일괄처리 단위로 처리를 한다. 즉, 물리적 유닛 벡터 길이는 16 레인이지만, 논리적인 벡터 길이는 64레인 분이다. 명령 유닛의 명령 버퍼와 프로그램 카운터는 64 스레드의 묶음인 Wavefront 단위로 제어한다.

 각각의 Wavefront는 같은 프로그램을 실행하는 경우에도 프로그램의 진행은 모이지 않는다. 따라서 각 Wavefront 마다, 프로그램 카운터가 필요하다. 또 CU (Compute Unit)는 다수의 Wavefront를 기동에서 동적으로 바꾸기 위해 많은 프로그램 카운터가 필요하다.

 


Bulldozer에 조금 비슷한 GCN의 멀티 Wavefront 아키텍처


 명령 유닛 속의 4개의 버퍼 유닛은 각각 4개의 벡터 연산 유닛에 대응하고 있다. 벡터 연산 유닛은 그림 중에서는 푸른 16개의 원기둥으로 나타내고 있으며, SIMD 0에서 SIMD3까지 이름이 붙여져 있다. SIMD 0 ~ 3의 4개의 벡터 연산 유닛은 각각 SIMD 0 ~ 3까지의 전용 명령 시퀀서가 제어하는​​ 특정 Wavefront의 명령을 실행한다.

 예를 들어, SIMD 0에서 실행하는 Wavefront가 SIMD 1로 이동하는 것은 없다. 원래 벡터 레지스터 자체가 각 벡터 유닛에 부속되어 레지스터를 상호 참조 할 수 없기 때문에 물리적으로 실행중인 Wavefront의 이동은 할 수 없다고. SIMD 0에서 버퍼된 Wavefront의 명령은 반드시 SIMD 0 유닛에 발행된다.

 즉, 명령 스케줄링적으로 CU는 4개의 분리된 벡터 유닛과 그에 대응하는 명령 유닛을 묶은 것이 된다. CPU로 비유를 하면 4개의 CPU 코어를 하나로 묶은듯한 모습이다.

 

 

CU에서의 명령 스케줄링


 이 구조는 AMD의 Bulldozer (불도저) 아키텍처의 멀티 쓰레드 CPU와 비교하면 알기 쉽다. Bulldozer의 CPU 모듈은 2개의 쓰레드를 동시에 실행시킬 수 있다. 2개의 정수 연산 유닛은 각 스레드가 점유하고 다른 유닛은 2 스레드에서 공유한다.

 GCN의 CU도 비슷한 구조를 가지고 있으며, 4개의 벡터 연산 유닛은 병렬로 움직이는 4개의 Wavefront가 각각 점유하지만, 다른 유닛은 공유한다. 그 의미는 GCN의 CU (Compute Unit)는 멀티 코어 구조를 가지고 있다고 말할 수 있다. 다만 실제로 GCN은 4개의 Wavefront뿐만 아니라 더 많은 Wavefront를 내부에서 움직일 수 있다. 레지스터 수가 허용하는 만큼 Wavefront를 시작할 수 있으며, 벡터 레지스터는 256개 이므로, 예를 들어, 각 스레드 당 32개의 벡터 레지스터를 할당한다면 각 벡터 유닛마다 8Wavefront를 동시에 움직이는 것이 가능하다 .

 

멀티 쓰레딩 아키텍처 비교

 

 GCN의 CU (Compute Unit)에서 명령 유닛 내부의 4 블록으로 나누어진 명령 버퍼 & 프로그램 카운터에 의해 4 그룹의 Wavefront 군이 집결된다. 그리고 집결된 Wavefront 중에서 명령 발행 중재 유닛 (Instruction Issue Arbitration)가 실행 가능한 명령을 조정하여 각 유닛에 발행한다.

 명령 발행 유닛은 1 사이클에 최대 5명령을 발행 가능하다. 발행 된 각각의 명령은 다른 Wavefront의 명령이다. 따라서 슈퍼 스칼라 CPU처럼 동시에 발행하는 명령의 의존성을 세밀하게 점검 할 필요가 없다. CPU 같은 복잡한 명령 제어기구를 가지지 않고도 비교적 간단한 명령 유닛에서 많은 명령을 병렬로 발행 가능하다.

 


Structure of Arrays (SOA)와 Array of Structures (AOS)

 

 GCN 실행 유닛의 핵심은 4개의 16레인 벡터 유닛이다. GPU는 벡터 유닛을 중심으로 구성되는데, 이 부분이 GCN과 기존의 AMD GPU에서 크게 다르다. 아키텍처 면에서의 가장 큰 변화는 "Structure of Arrays (SOA)"방식으로 전환한 것이다. 벡터 연산을 SOA로 하는 것으로, 범용 컴퓨팅 성능과 프로그램성을 올리려 한다.

 벡터 유닛 사용법에는 두가지 방법이 있다. "Array of Structures (AOS)" 또는 "팩크드 (Packed)"라는 방식과 "Structure of Arrays (SOA) "또는 "스칼라 (Scalar) "라고 부르는 방식이다. 아래의 그림처럼 벡터 유닛상에서 어떤 정렬 방식으로 데이터를 다루는지가 다르다.

 

 

 

AOS와 SOA의 비교

 


그림의 예는 16레인 벡터 유닛에서 64개의 데이터를 처리하는 경우다. 벡터 유닛에 포함된 16개의 연산 유닛은 SIMD (Single Instruction, Multiple Data) 형태로 16개의 유닛이 같은 명령을 16개의 다른 데이터에 대해 실행한다. CPU는 4레인 (단정밀도 부동 소수점 연산의 경우)의 SSE 또는 8 레인의 AVX (Advanced Vector Extensions)이지만, 현재의 GPU는 16레인 정도가 일반적이다.

 그림의 예에서는 16개의 픽셀 데이터를 처리하는 것을 상정하고 있다. 각 픽셀이 RGB의 3 컬러 데이터와 알파 데이터를 가지고 있기 때문에 1픽셀 당 RGBA의 4 데이터가 있다. 16 픽셀만큼의 RGBA로 데이터는 총 64개가 된다. 벡터 유닛은 16 레인이므로, 4 사이클로 실행 가능하다.

 AOS의 경우는 RGBA의 4 데이터 팩을 4개 나란히 16 레인을 채운다. 즉, 각 사이클에 4픽셀을 동시에 처리한다. RGBA의 데이터 팩은 무너뜨리지 않는다.

 반면 Structure of Arrays (SOA)에서는 RGBA의 4 데이터 팩을 무너뜨려 버린다. 16 개의 픽셀 모든 데이터를 순차로 처리해 간다. 예를 들어 16픽셀 중 R에 대해서 명령을 실행한 후 16개의 G에 대해 명령을 실행한다.

 


SOA로 흐르는 GPU 아키텍처


 이렇게 보면 AOS와 SOA는 둘 다 똑같이 효율적으로 보인다. 그런데 경우에 따라서는 효율이 크게 바뀔 가능성이 있다. 그것은 AOS는 데이터 팩을 잘 갖추지 않으면 안되기 때문이다. 예를 들어, 데이터가 정점의 XYZ의 3 값인 경우에는 16 레인에 잘 맞지 않는다. 아래의 그림이 그 예다.

 

 

AOS에 XYZ의 3 값을 거둔 경우

 


 이 경우 AOS는 XYZ 3 데이터 뒤에 빈 슬롯을 넣는 등의 궁리가 필요하고, 그 경우는 16 레인에서 4 정점 밖에 처리 할 수​​ 없다. 연산 유닛은 4분의 1이 노는 것으로, 75%의 가동률로 떨어진다. 벡터 유닛을 AOS에 최적화하여 4 레인마다 분할한 경우는 이 방법 밖에없고, 효율이 악화된다.

 반면 SOA의 경우는 어떤 경우에도 100%의 가동률을 얻는 것이 가능하다. 물론, 16 쓰레드가 갖추어진 경우의 이야기다. SOA는 각 쓰레드의 XYZ 3 데이터를 각 사이클에 순번으로 실행하는 정도이므로, 낭비가 생기지 않는다. AOS는 16 정점의 연산에 4 사이클이 걸리는데, SOA라면 3사이클에 끝나 버린다. 효율도 스피드도 SOA 쪽이다. 만약 1 쓰레드에 1 데이터만의 경우는, 한층 AOS와 SOA의 효율 차이가 벌어진다.

 물론 반대급부도 있다. SOA는 SOA의 구조에 맞게 데이터의 정렬을 변경 할 필요가 있다. 데이터는 메모리상에서 AOS에 적합한 정렬 방식으로 있는 경우가 많다. 그것을 정렬을 바꿔서 레지스터에 수납할 필요가 있다. 그러나 데이터 정렬을 바꾸는 오버 헤드가 있어도 연산이 많은 경우는 SOA가 유리하다.

 SOA에서는 16 레인에서 16 쓰레드가 모두 같은 명령을 실행할 필요가 있다. 따라서 스레드에 의해 명령 흐름이 분기하는 경우에는 문제가 생기고 만다. 따라서 SOA를 전제로 하는 광폭 벡터 유닛에서는 마스크 레지스터를 통한 프레디케이션을 행하는 것이 일반적이다.

 

 

벡터 조건 분기

 

 프레디케이션에서는 각 레인의 스레드마다, 명령을 실행는가 안하는가 (또는​​ 연산 결과를 레지스터에 기록하거나 기록하지 않거나)를 마스크 레지스터에 의해 선택 가능하다. 따라서 레인상의 쓰레드에 분기가 발생해도 대응할 수 있다.

 NVIDIA는 GPU 아키텍처를 단일(unified)형으로 변경한 GeForce 8 (G80) 세대부터 SOA 아키텍처를 취했다. Intel의 Larrabee에서는 SOA에 최적인 아키텍처를 취했다. 반면 AMD는 다른 방식으로 짧은 벡터 유닛을 16개, SIMD (Single Instruction, Multiple Data)로 작동하는 방법을 취했다. 그러나 GCN에서는 NVIDIA와 Intel처럼 SOA에 맞춘 16레인 벡터 유닛으로 변경했다. 그 이유는 범용 컴퓨팅 때의 효율을 높이기 위해서다. 이번 AMD의 아키텍처 변경의 핵심은 거기에 있다. 다음 기사에서 설명하자.

 

2012년 2월 1일

 

[분석정보] 피크성능에서 실효성능으로 포커스가 바뀐 AMD의 GPU 아키텍처

 

 

[정보분석] AMD 2013년까지 로드맵 공개

 

 

[분석정보] 크게 다른 Radeon HD 2000과 GeForce 8000의 아키텍처

 

 

[분석정보] 인텔 GDC에서 라라비 명령 세트의 개요를 공개

 

 

[분석정보] 라라비 (Larrabee)의 비장의 카드 공유 가상 메모리

 

 

 

[정보분석] CPU와 GPU의 메모리 공간을 통일하는 AMD의 hUMA 아키텍처

 

 

[분석정보] AMD의 차세대 APU Kaveri (카베리)는 아키텍처의 전환점