GN⁺: Tiny GPU: Verilog으로 구현한 최소한의 GPU
(github.com/adam-maj)tiny-gpu 아키텍처 개요
GPU
- 한 번에 하나의 커널을 실행하도록 구축됨
- 커널을 실행하기 위해서는 다음 작업 필요:
- 커널 코드로 전역 프로그램 메모리 로드
- 필요한 데이터로 데이터 메모리 로드
- 디바이스 제어 레지스터에서 실행할 스레드 수 지정
- 시작 신호를 HIGH로 설정하여 커널 실행
- GPU는 다음 유닛으로 구성:
- 디바이스 제어 레지스터
- 디스패처
- 가변 수의 컴퓨팅 코어
- 데이터 메모리 및 프로그램 메모리용 메모리 컨트롤러
- 캐시
메모리
- GPU는 외부 글로벌 메모리와 인터페이스하도록 구축됨
- 데이터 메모리와 프로그램 메모리가 단순화를 위해 분리됨
- 글로벌 메모리는 고정된 읽기/쓰기 대역폭을 가짐
- 메모리 컨트롤러는 컴퓨팅 코어에서 메모리로의 아웃고잉 요청을 모두 추적하고, 실제 외부 메모리 대역폭에 따라 요청을 조절하며, 외부 메모리에서 적절한 리소스로 응답을 릴레이함
- 캐시는 반복적으로 요청되는 데이터를 저장하여 메모리 대역폭 사용을 줄임
코어
- 각 코어는 컴퓨팅 리소스 보유
- 단순화된 GPU에서 각 코어는 한 번에 하나의 블록을 처리하고, 블록의 각 스레드에 대해 전용 ALU, LSU, PC 및 레지스터 파일을 가짐
- 스케줄러는 스레드 실행을 관리하고, 블록을 완료하기 전에 새 블록을 선택하지 않음
- 페쳐는 현재 프로그램 카운터에서 명령어를 비동기적으로 가져옴
- 디코더는 페치된 명령어를 스레드 실행을 위한 제어 신호로 디코딩함
- 각 스레드는 전용 레지스터 파일 세트를 가짐
- ALU는 스레드별 전용 연산 논리 장치
- LSU는 전역 데이터 메모리에 액세스하기 위한 스레드별 전용 로드-스토어 유닛
- PC는 각 스레드에서 실행할 다음 명령어를 결정하는 전용 프로그램 카운터
ISA
- 간단한 11개 명령어 ISA 구현
- 행렬 덧셈 및 곱셈 등의 간단한 커널을 위해 구축됨
- 기본 산술 연산, 메모리 로드/스토어, 분기, 상수 로드 등 지원
실행
- 각 코어는 명령어를 실행하기 위해 페치, 디코드, 요청, 대기, 실행, 업데이트의 단계를 거침
- 각 스레드는 레지스터 파일의 데이터에 대한 계산을 수행하기 위해 실행 경로를 따름
- SIMD 기능을 위해 읽기 전용 레지스터에 블록 인덱스, 차원, 스레드 인덱스 값이 있음
커널
- 행렬 덧셈 및 곱셈 커널을 ISA로 작성하여 SIMD 프로그래밍과 GPU 실행을 입증
- 테스트 파일로 GPU에서 커널 실행을 완전히 시뮬레이션하고 데이터 메모리 상태와 실행 추적을 생성할 수 있음
시뮬레이션
- iverilog와 cocotb 설치 후 make 명령으로 커널 시뮬레이션 실행 가능
- 로그 파일에 초기/최종 데이터 메모리 상태와 커널의 완전한 실행 추적이 출력됨
고급 기능
- 성능 및 기능을 크게 향상시키는 현대 GPU의 많은 추가 기능들이 단순화를 위해 생략됨
- 다중 계층 캐시 및 공유 메모리, 메모리 병합, 파이프라이닝, Warp 스케줄링, 분기 분기, 동기화 및 장벽 등의 기능 논의
GN⁺의 의견
- 간단하고 이해하기 쉽게 GPU 아키텍처와 SIMD 프로그래밍 모델의 핵심을 잘 설명하고 있음. 특히 행렬 연산 커널 예제를 통해 실제 GPU에서 어떻게 병렬 처리가 이루어지는지 잘 보여줌.
- 현대 GPU에서 사용되는 고급 기능들도 잘 정리되어 있어, tiny-gpu를 이해한 후에는 좀 더 복잡한 GPU 아키텍처를 공부하는데 도움이 될 것 같음.
- 다만 실제 그래픽스 파이프라인 기능은 빠져있어서, 그래픽스에 특화된 하드웨어가 어떻게 동작하는지는 다루지 않음. 그래픽스에 관심있는 사람은 아쉬울 수 있음.
- 오픈소스로 공개된 다른 GPU 아키텍처인 MIAOW나 GPGPU-Sim 등과 비교해보면, 좀 더 현실적인 GPU를 이해하는데 도움이 될 것 같음.
- 앞으로 분기 분기, 메모리 병합, 파이프라이닝 등의 기능이 추가된다면 더욱 실용적인 학습 자료가 될 것으로 기대됨. 개발에 기여할 수 있는 오픈소스 프로젝트라는 점도 매력적임.
Hacker News 의견
-
Intel은 GPU에 대한 많은 기술 문서를 공개하고 있음. 810/815 매뉴얼도 온라인에서 찾을 수 있음. 855/910/915/945를 제외하고는 문서화가 일관성 있게 이루어지고 있음.
-
오픈 코어 GPU 작업을 격려함.
-
NyuziProcessor라는 또 다른 오픈소스 GPU 프로젝트가 있음. (https://github.com/jbush001/NyuziProcessor)
-
FPGA에 입문하고 싶지만, 어디서부터 시작해야 할지 파악하기 어렵고 분야 자체가 위압적으로 느껴짐.
-
최종 목표는 LLM(Large Language Model)을 위한 가속 카드를 만드는 것임. 메모리 오프로딩 부분을 제외하고는 이 프로젝트와 유사한 부분이 많을 것임.
-
순차적인 always 블록에서 non-blocking과 blocking 할당 연산자를 혼합하는 이유에 대해 질문함.
-
예전에 VHDL로 비슷한 작업을 했었음. opencores라는 사이트에 다양한 오픈소스 HDL 프로젝트가 있었음. 오늘날 HPC 수준의 대규모 분산 HDL 시뮬레이터가 있는지 궁금함. 최신 GPU를 활용하여 RTL 수준 시뮬레이션을 수행하는 것이 합리적임.
-
하드웨어 프로젝트가 오픈되는 것을 좋아함. 하지만 이것은 SIMD 코프로세서라고 주장할 수 있음. GPU가 되려면 적어도 일종의 디스플레이 출력이 있어야 함. 최근 Nvidia 등이 그래픽 아키텍처의 서버 전용 변종을 GPU로 판매하면서 용어가 다소 느슨해졌지만, GPU 설계의 "그래픽" 부분은 여전히 복잡성의 상당 부분을 차지함.
-
ALU가 하드웨어 수준에서 DIV 명령어를 직접 구현하는 것은 일반적인지 의문. 현대 CUDA 코어와 같은 곳에서 실제 명령어로 사용되는 것인지, 아니면 일반적으로 소프트웨어 에뮬레이션인지 궁금함. 실제 하드웨어 나누기 회로는 많은 공간을 차지하므로 GPU ALU에서는 기대하지 않았음. Verilog에서 "DIV: begin alu_out_reg <= rs / rt; end"라고 쓰기는 쉽지만 실리콘에서는 많은 공간을 차지함. 하지만 Verilog만 시뮬레이션하는 사람은 이를 알지 못할 수 있음.
-
그래픽 기능을 제공하지 않는 또 다른 "GPU". 이런 것들은 다른 이름으로 불려야 한다는 의견.
-
스레드가 병렬로 처리된다고 가정하고, 각 명령어 후에 모든 스레드가 동일한 프로그램 카운터로 "수렴"한다고 단순화했음. 실제 GPU에서는 개별 스레드가 다른 PC로 분기할 수 있어 branch divergence가 발생함. 실리콘으로 GPU를 만들기 전에 GPU 프로그래밍을 해보는 게 좋겠음. SIMD도 아님. (LED를 깜박이는 회로를 조립해 CPU를 만들었다고 주장한 사람과 동일)