본문으로 건너뛰기

고성능컴퓨터시스템 구조(2)

1. 다중 프로세서 시스템 구조

다중 프로세서 시스템에서 각 프로세서가 캐시를 보유할 때 발생하는 주요 문제점은 데이터 일관성입니다. 주기억장치에 저장된 공유 데이터가 여러 캐시에 적재되고, 특정 프로세서가 이 데이터를 변경할 경우, 주기억장치와 다른 캐시에 저장된 데이터 값이 서로 달라지는 상황이 발생합니다. 이러한 문제를 해결하기 위해 캐시 일관성 유지 프로토콜(cache coherence protocol) 이 필요합니다.

1.1. 캐시 쓰기 정책에 따른 데이터 불일치 문제

  • Write-through 정책:
    • 프로세서가 캐시의 데이터를 수정할 때 동시에 주기억장치에도 갱신하는 방식
    • 버스 감시(Bus Snooping) 이용: 프로세서가 어떤 캐시 라인을 수정하는 경우에 그 사실을 방송(broadcasting)하고, 버스 상의 상황을 감시(snooping)하는 하드웨어 구현을 통해 일관성 유지
    • 스누프 제어기(Snoop Controller) 동작: 주기억장치에 대한 쓰기 동작의 주소가 자신의 캐시에 있는지 검사하여, 존재한다면 해당 블록을 무효화(invalidate)
    • 캐시 데이터 상태: 유효(V: Valid), 무효(I: Invalid)
    • 예시: P1이 X를 X'로 변경하면 P2의 캐시에 있는 X는 무효(I) 상태가 되고, P2가 X를 액세스하면 캐시 미스 발생 후 주기억장치로부터 X'가 읽혀와 유효(V) 상태로 변경
  • Write-back 정책:
    • 프로세서가 캐시의 데이터를 변경해도 주기억장치의 내용은 즉시 갱신되지 않는 방식
    • 다른 스누프 제어기가 변경 사실을 알 수 없으므로, 변경된 캐시의 스누프 제어기가 무효화 신호(invalidate signal) 를 다른 스누프 제어기들에게 통보하여 일관성 유지

1.2. MESI 프로토콜 (Write-back 일관성 유지)

Write-back 정책에서 캐시 데이터의 상태를 효율적으로 관리하기 위해 MESI 프로토콜이 사용됩니다. MESI는 각 캐시 라인의 상태를 네 가지로 정의합니다.

상태의미설명
MModified수정 상태 – 데이터가 수정되었으며 주기억장치에 기록되지 않은 상태. 해당 캐시만이 유일한 복사본을 가짐
EExclusive배타 상태 – 유일한 복사본이며 주기억장치 내용과 동일한 상태. 아직 수정되지 않음
SShared공유 상태 – 데이터가 두 개 이상의 프로세서 캐시에 적재되어 있는 상태. 주기억장치 내용과 동일함
IInvalid무효 상태 – 데이터가 다른 프로세서에 의해 수정되어 더 이상 유효하지 않은 상태

MESI 프로토콜의 주요 상태 전이 (예시):

  • 데이터를 처음 읽는 경우: 읽기 미스 발생 시, 주기억장치로부터 데이터를 읽어온 후 상태를 '배타(E)'로 설정
  • 캐시에 적재된 데이터 변경: 쓰기 적중 발생 시, 데이터를 수정한 후 상태를 '수정(M)'으로 설정
  • 데이터가 공유되는 경우: 다른 프로세서가 'M' 상태의 데이터를 읽으려 할 때, 해당 프로세서의 스누프 제어기가 읽기 동작을 중단시키고, 자신의 데이터를 읽으려는 프로세스(P2)로 전송(캐시 간 전송)하며, 주기억장치도 갱신. 이때 데이터의 상태는 모두 '공유(S)'로 변경. 캐시 간 전송이 지원되지 않는 시스템의 경우 '재시도(retry)'를 요구
  • 공유 상태의 데이터 변경: 공유(S) 상태의 데이터를 특정 프로세서가 갱신하면, 해당 프로세서가 무효화 신호를 발송하고, 다른 캐시들은 X의 상태를 '무효(I)'로 변경하며, 갱신한 프로세서는 '수정(M)'으로 변경
  • 'M' 상태 데이터 재변경: 쓰기 적중 발생 시 데이터만 변경되고 상태는 불변
  • 'I' 상태 데이터 변경: 'I' 상태의 데이터를 수정하기 위해 읽으려 하면 쓰기 미스가 발생하며, '수정을 위한 읽기(RWITM)'가 시작됨. 데이터를 소유한 캐시가 새 값을 보내주고, 자신의 상태는 'I'로 변경하며, 수정하는 캐시는 'M'으로 변경

2. 그래픽 처리 장치 (GPU, Graphics Processing Unit)

GPU는 "NVIDIA사에 의해 개발된 그래픽처리 유니트(GPU)를 활용한 데이터 병렬 응용을 위한 보조프로세서"로, 1999년에 처음 개발되었습니다. 이후 "통합된 그래픽 및 계산 구조(unified graphic and compute architecture)"와 "CUDA(Compute Unified Device Architecture) 프로그래밍 모델" 덕분에 다양한 데이터 병렬 응용을 위한 범용 GPU로 발전했습니다.

2.1. CUDA 프로그래밍 모델

CUDA는 "일반적인 프로그래밍 언어들을 이용하여 GPU를 위한 프로그램을 쉽게 작성할 수 있게 해주는 프로그래머-친화적 병렬컴퓨팅 플랫폼"입니다.

  • 컴퓨팅 시스템 모델:
    • 호스트(host): 일반적인 CPU로 순차적 프로그램 처리
    • 디바이스(device): GPU와 같은 병렬 프로세서
  • GPU 내부 구성:
    • 다수의 스트리밍 다중프로세서(Streaming Multiprocessor: SM)로 구성, 각 SM 내에는 다수의 스트리밍 프로세서(streaming processor: SP, CUDA 코어)
  • CUDA 프로그램 구성:
    • '호스트 코드(host code)'와 '디바이스 코드(device code)'로 구성
    • 호스트 코드: ANSI C 기반의 순차적 프로그램
    • 디바이스 코드: ANSI C 코드와 '커널 함수(kernel function)'로 구성
    • 커널 함수: 병렬 함수 및 데이터 구조를 명시하는 키워드들을 확장한 형태로 작성된 코드로서, 디바이스가 실행하는 부분(병렬처리 가능 부분)
    • 스레드(thread): 커널 함수의 한 인스턴스로, GPU의 SP(CUDA 코어)에 의해 실행
  • CUDA 프로그램 실행 모델:
    • 그리드(grid): 하나의 병렬 커널에 의해 생성되는 스레드 전체
    • 블록(block): 그리드 내의 스레드들을 적절한 수의 스레드들로 분할한 단위, 하나의 SM에 할당
    • 스레드 ID: 커널 함수 내의 내장 변수(threadIdx)로 액세스, 스레드 및 데이터 기억장치 주소 계산에 사용

2.2. CUDA 프로그램 실행 과정

  1. 호스트가 순차적 코드를 실행
  2. 커널 함수가 호출되면, 병렬 커널 코드가 디바이스로 보내짐
  3. 디바이스에서 커널이 그리드(블록 및 스레드 포함)를 생성하여 SM들에게 할당, SM 내의 SP들이 한 스레드씩을 담당하여 실행
  4. 모든 스레드들의 실행이 완료되면 그리드가 종료되고, 결과값들이 호스트로 전송
  5. 호스트는 다음 순차적 코드를 실행하며, 또 다른 커널을 만난다면 위 과정을 반복

2.3. GPU 기억장치 계층

GPU는 효율적인 데이터 처리를 위해 계층적인 기억장치 구조를 가집니다.

  • 지역 기억장치(local memory): 각 스레드가 사용하며 주로 레지스터 세트로 구현
  • 공유 기억장치(shared memory): 같은 블록에 포함된 스레드들이 공동으로 사용
  • 전역 기억장치(global memory): 모든 응용 프로그램들이 생성한 그리드들이 공유하는 기억장치, 호스트와 GPU 간의 데이터 교환에도 사용

2.4. GPU의 내부 구조 (Fermi 구조 사례)

NVIDIA Fermi GPU는 다음과 같은 주요 구성 요소를 가집니다.

  • 스트리밍 다중프로세서(SM): Fermi GPU는 16개의 SM으로 구성, 각 SM은 32개의 CUDA 코어(SP)를 포함하여 총 512개의 CUDA 코어
  • SM 내부 구성:
    • GPU 프로세서 코어들(32개의 CUDA 코어들)
    • 2개의 왑 스케줄러(warp scheduler) 및 디스패치 포트: 왑 단위의 스레드 할당
    • 왑(warp): SM이 한 번에 수행할 수 있는 32개의 스레드 묶음
    • 16개의 적재/저장 유니트(load/store unit): 캐시 및 DRAM 액세스
    • 4개의 SFU(Special Function Unit): 초월 함수 계산
    • 32K개의 32-비트 레지스터들
    • 공유 기억장치 및 L1 캐시(전체 64KB)

결론

고성능 컴퓨터 시스템의 핵심 원리를 이해하는 데 필수적인 다중 프로세서의 캐시 일관성 문제와 이를 해결하기 위한 프로토콜(Write-through, Write-back, MESI), 그리고 현대 병렬 컴퓨팅의 주역인 GPU의 구조와 프로그래밍 모델(CUDA)을 체계적으로 설명합니다. 이 내용들은 복잡한 컴퓨터 아키텍처를 이해하고 고성능 시스템 설계를 위한 기반 지식을 제공합니다.