|
| 1 | +--- |
| 2 | +sidebar_position: 14 |
| 3 | +title: 고성능컴퓨터시스템 구조(2) |
| 4 | +description: 고성능 컴퓨터 시스템의 구조와 원리를 이해하기 위한 다중 프로세서 시스템과 GPU의 캐시 일관성 문제, MESI 프로토콜, CUDA 프로그래밍 모델 등을 설명합니다. |
| 5 | +--- |
| 6 | + |
| 7 | +## 1. 다중 프로세서 시스템 구조 |
| 8 | + |
| 9 | +다중 프로세서 시스템에서 각 프로세서가 캐시를 보유할 때 발생하는 주요 문제점은 **데이터 일관성**입니다. 주기억장치에 저장된 공유 데이터가 여러 캐시에 적재되고, 특정 프로세서가 이 데이터를 변경할 경우, 주기억장치와 다른 캐시에 저장된 데이터 값이 서로 달라지는 상황이 발생합니다. 이러한 문제를 해결하기 위해 **캐시 일관성 유지 프로토콜(cache coherence protocol)** 이 필요합니다. |
| 10 | + |
| 11 | +### 1.1. 캐시 쓰기 정책에 따른 데이터 불일치 문제 |
| 12 | + |
| 13 | +- **Write-through 정책:** |
| 14 | + - 프로세서가 캐시의 데이터를 수정할 때 동시에 주기억장치에도 갱신하는 방식 |
| 15 | + - **버스 감시(Bus Snooping) 이용:** 프로세서가 어떤 캐시 라인을 수정하는 경우에 그 사실을 방송(broadcasting)하고, 버스 상의 상황을 감시(snooping)하는 하드웨어 구현을 통해 일관성 유지 |
| 16 | + - **스누프 제어기(Snoop Controller) 동작:** 주기억장치에 대한 쓰기 동작의 주소가 자신의 캐시에 있는지 검사하여, 존재한다면 해당 블록을 무효화(invalidate) |
| 17 | + - **캐시 데이터 상태:** 유효(V: Valid), 무효(I: Invalid) |
| 18 | + - **예시:** P1이 X를 X'로 변경하면 P2의 캐시에 있는 X는 무효(I) 상태가 되고, P2가 X를 액세스하면 캐시 미스 발생 후 주기억장치로부터 X'가 읽혀와 유효(V) 상태로 변경 |
| 19 | +- **Write-back 정책:** |
| 20 | + - 프로세서가 캐시의 데이터를 변경해도 주기억장치의 내용은 즉시 갱신되지 않는 방식 |
| 21 | + - 다른 스누프 제어기가 변경 사실을 알 수 없으므로, 변경된 캐시의 스누프 제어기가 **무효화 신호(invalidate signal)** 를 다른 스누프 제어기들에게 통보하여 일관성 유지 |
| 22 | + |
| 23 | +### 1.2. MESI 프로토콜 (Write-back 일관성 유지) |
| 24 | + |
| 25 | +Write-back 정책에서 캐시 데이터의 상태를 효율적으로 관리하기 위해 **MESI 프로토콜**이 사용됩니다. MESI는 각 캐시 라인의 상태를 네 가지로 정의합니다. |
| 26 | + |
| 27 | +| 상태 | 의미 | 설명 | |
| 28 | +| ---- | --------- | ----------------------------------------------------------------------------------------------------- | |
| 29 | +| M | Modified | 수정 상태 – 데이터가 수정되었으며 주기억장치에 기록되지 않은 상태. 해당 캐시만이 유일한 복사본을 가짐 | |
| 30 | +| E | Exclusive | 배타 상태 – 유일한 복사본이며 주기억장치 내용과 동일한 상태. 아직 수정되지 않음 | |
| 31 | +| S | Shared | 공유 상태 – 데이터가 두 개 이상의 프로세서 캐시에 적재되어 있는 상태. 주기억장치 내용과 동일함 | |
| 32 | +| I | Invalid | 무효 상태 – 데이터가 다른 프로세서에 의해 수정되어 더 이상 유효하지 않은 상태 | |
| 33 | + |
| 34 | +**MESI 프로토콜의 주요 상태 전이 (예시):** |
| 35 | + |
| 36 | +- **데이터를 처음 읽는 경우:** 읽기 미스 발생 시, 주기억장치로부터 데이터를 읽어온 후 상태를 '배타(E)'로 설정 |
| 37 | +- **캐시에 적재된 데이터 변경:** 쓰기 적중 발생 시, 데이터를 수정한 후 상태를 '수정(M)'으로 설정 |
| 38 | +- **데이터가 공유되는 경우:** 다른 프로세서가 'M' 상태의 데이터를 읽으려 할 때, 해당 프로세서의 스누프 제어기가 읽기 동작을 중단시키고, 자신의 데이터를 읽으려는 프로세스(P2)로 전송(캐시 간 전송)하며, 주기억장치도 갱신. 이때 데이터의 상태는 모두 '공유(S)'로 변경. 캐시 간 전송이 지원되지 않는 시스템의 경우 '재시도(retry)'를 요구 |
| 39 | +- **공유 상태의 데이터 변경:** 공유(S) 상태의 데이터를 특정 프로세서가 갱신하면, 해당 프로세서가 무효화 신호를 발송하고, 다른 캐시들은 X의 상태를 '무효(I)'로 변경하며, 갱신한 프로세서는 '수정(M)'으로 변경 |
| 40 | +- **'M' 상태 데이터 재변경:** 쓰기 적중 발생 시 데이터만 변경되고 상태는 불변 |
| 41 | +- **'I' 상태 데이터 변경:** 'I' 상태의 데이터를 수정하기 위해 읽으려 하면 쓰기 미스가 발생하며, '수정을 위한 읽기(RWITM)'가 시작됨. 데이터를 소유한 캐시가 새 값을 보내주고, 자신의 상태는 'I'로 변경하며, 수정하는 캐시는 'M'으로 변경 |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +## 2. 그래픽 처리 장치 (GPU, Graphics Processing Unit) |
| 46 | + |
| 47 | +GPU는 "NVIDIA사에 의해 개발된 그래픽처리 유니트(GPU)를 활용한 데이터 병렬 응용을 위한 보조프로세서"로, 1999년에 처음 개발되었습니다. 이후 "통합된 그래픽 및 계산 구조(unified graphic and compute architecture)"와 "CUDA(Compute Unified Device Architecture) 프로그래밍 모델" 덕분에 다양한 데이터 병렬 응용을 위한 범용 GPU로 발전했습니다. |
| 48 | + |
| 49 | +### 2.1. CUDA 프로그래밍 모델 |
| 50 | + |
| 51 | +CUDA는 "일반적인 프로그래밍 언어들을 이용하여 GPU를 위한 프로그램을 쉽게 작성할 수 있게 해주는 프로그래머-친화적 병렬컴퓨팅 플랫폼"입니다. |
| 52 | + |
| 53 | +- **컴퓨팅 시스템 모델:** |
| 54 | + - **호스트(host):** 일반적인 CPU로 순차적 프로그램 처리 |
| 55 | + - **디바이스(device):** GPU와 같은 병렬 프로세서 |
| 56 | +- **GPU 내부 구성:** |
| 57 | + - 다수의 스트리밍 다중프로세서(Streaming Multiprocessor: SM)로 구성, 각 SM 내에는 다수의 스트리밍 프로세서(streaming processor: SP, CUDA 코어) |
| 58 | +- **CUDA 프로그램 구성:** |
| 59 | + - '호스트 코드(host code)'와 '디바이스 코드(device code)'로 구성 |
| 60 | + - **호스트 코드:** ANSI C 기반의 순차적 프로그램 |
| 61 | + - **디바이스 코드:** ANSI C 코드와 '커널 함수(kernel function)'로 구성 |
| 62 | + - **커널 함수:** 병렬 함수 및 데이터 구조를 명시하는 키워드들을 확장한 형태로 작성된 코드로서, 디바이스가 실행하는 부분(병렬처리 가능 부분) |
| 63 | + - **스레드(thread):** 커널 함수의 한 인스턴스로, GPU의 SP(CUDA 코어)에 의해 실행 |
| 64 | +- **CUDA 프로그램 실행 모델:** |
| 65 | + - **그리드(grid):** 하나의 병렬 커널에 의해 생성되는 스레드 전체 |
| 66 | + - **블록(block):** 그리드 내의 스레드들을 적절한 수의 스레드들로 분할한 단위, 하나의 SM에 할당 |
| 67 | + - **스레드 ID:** 커널 함수 내의 내장 변수(threadIdx)로 액세스, 스레드 및 데이터 기억장치 주소 계산에 사용 |
| 68 | + |
| 69 | +### 2.2. CUDA 프로그램 실행 과정 |
| 70 | + |
| 71 | +1. 호스트가 순차적 코드를 실행 |
| 72 | +2. 커널 함수가 호출되면, 병렬 커널 코드가 디바이스로 보내짐 |
| 73 | +3. 디바이스에서 커널이 그리드(블록 및 스레드 포함)를 생성하여 SM들에게 할당, SM 내의 SP들이 한 스레드씩을 담당하여 실행 |
| 74 | +4. 모든 스레드들의 실행이 완료되면 그리드가 종료되고, 결과값들이 호스트로 전송 |
| 75 | +5. 호스트는 다음 순차적 코드를 실행하며, 또 다른 커널을 만난다면 위 과정을 반복 |
| 76 | + |
| 77 | +### 2.3. GPU 기억장치 계층 |
| 78 | + |
| 79 | +GPU는 효율적인 데이터 처리를 위해 계층적인 기억장치 구조를 가집니다. |
| 80 | + |
| 81 | +- **지역 기억장치(local memory):** 각 스레드가 사용하며 주로 레지스터 세트로 구현 |
| 82 | +- **공유 기억장치(shared memory):** 같은 블록에 포함된 스레드들이 공동으로 사용 |
| 83 | +- **전역 기억장치(global memory):** 모든 응용 프로그램들이 생성한 그리드들이 공유하는 기억장치, 호스트와 GPU 간의 데이터 교환에도 사용 |
| 84 | + |
| 85 | +### 2.4. GPU의 내부 구조 (Fermi 구조 사례) |
| 86 | + |
| 87 | +NVIDIA Fermi GPU는 다음과 같은 주요 구성 요소를 가집니다. |
| 88 | + |
| 89 | +- **스트리밍 다중프로세서(SM):** Fermi GPU는 16개의 SM으로 구성, 각 SM은 32개의 CUDA 코어(SP)를 포함하여 총 512개의 CUDA 코어 |
| 90 | +- **SM 내부 구성:** |
| 91 | + - GPU 프로세서 코어들(32개의 CUDA 코어들) |
| 92 | + - 2개의 왑 스케줄러(warp scheduler) 및 디스패치 포트: 왑 단위의 스레드 할당 |
| 93 | + - **왑(warp):** SM이 한 번에 수행할 수 있는 32개의 스레드 묶음 |
| 94 | + - 16개의 적재/저장 유니트(load/store unit): 캐시 및 DRAM 액세스 |
| 95 | + - 4개의 SFU(Special Function Unit): 초월 함수 계산 |
| 96 | + - 32K개의 32-비트 레지스터들 |
| 97 | + - 공유 기억장치 및 L1 캐시(전체 64KB) |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +## 결론 |
| 102 | + |
| 103 | +고성능 컴퓨터 시스템의 핵심 원리를 이해하는 데 필수적인 다중 프로세서의 캐시 일관성 문제와 이를 해결하기 위한 프로토콜(Write-through, Write-back, MESI), 그리고 현대 병렬 컴퓨팅의 주역인 GPU의 구조와 프로그래밍 모델(CUDA)을 체계적으로 설명합니다. 이 내용들은 복잡한 컴퓨터 아키텍처를 이해하고 고성능 시스템 설계를 위한 기반 지식을 제공합니다. |
0 commit comments