[CS] DMA(Direct Memory Access)

DMA란?

DMA(Direct Memory Access)는 CPU를 거치지 않고 장치(디스크, 네트워크 카드, 사운드 카드 등)가 직접 메모리(RAM)와 데이터를 주고받는 방식을 말한다.

DMA 설명 : 해당 이미지는 GPT로 생성되었다.

  • 기존: 사장님이 직접 배달 → 시간이 오래 걸리고 가게 일에 집중 못함
  • DMA: 라이더에게 맡기고 → 사장님은 요리에 집중, 배달 완료되면 알림을 받는다.

동작 과정

① CPU가 설정한다

  • CPU는 DMA 컨트롤러에게 세 가지를 알려준다:
    1. 어디서부터 복사할지 (source 주소)
    2. 어디로 복사할지 (destination 주소)
    3. 얼마나 복사할지 (전송할 데이터 크기)

② DMA가 전송한다

  • CPU는 이제 손을 뗀다.
  • DMA 컨트롤러가 메모리와 장치 간에 직접 데이터를 주고받는다.

③ 전송 완료 후 알림

  • 데이터 복사가 끝나면, DMA 컨트롤러가 Interrupt(하드웨어 인터럽트)를 발생시킨다.
  • CPU는 그제야 "아, 데이터 다 옮겨졌구나"를 안다.

DMA가 중요한 이유

  • CPU를 자유롭게 해 준다 → CPU는 다른 계산/작업을 할 수 있다.
  • I/O 처리 속도를 높인다 → 대용량 데이터도 빠르게 복사 가능.
  • 효율적인 시스템 리소스 사용 → 메모리-장치 간 대역폭 활용 극대화.

DMA 방식의 종류

종류 설명
Burst DMA 한 번에 많은 데이터를 한꺼번에 전송 (속도 빠름, 메모리 독점 가능성 있음)
Cycle Stealing DMA 메모리 버스를 잠깐씩 빌려서 전송 (CPU랑 번갈아 사용 → CPU 영향 최소화)
Transparent DMA CPU가 메모리를 안 쓰는 순간에만 몰래 전송 (CPU 입장에서 거의 티가 안 남)

→ 주로 사용 환경에 따라 최적화 방법을 다르게 선택한다.

실제 운영체제(OS)에서의 DMA

운영체제 커널은 보통:

  • I/O 요청 시 DMA를 설정하고
  • Interrupt 기반으로 완료를 통지받고
  • 디바이스 드라이버가 전송 완료 후 데이터를 처리한다.

리눅스 커널 같은 경우 I/O 시스템 콜(read(), write())을 통해,
하드웨어에 DMA를 설정하고, interrupt를 기다리는 구조를 가진다.

세세한 기술적 주의사항

 

  • 버스 충돌(Bus Contention) 문제
    • CPU와 DMA가 동시에 메모리 버스를 사용하려고 하면 충돌할 수 있음.
    • 이를 조율하는 방식이 버스 중재(Bus Arbitration)이다.
  • 캐시 일관성 문제
    • CPU는 캐시를 사용하고, DMA는 메모리에 직접 접근하므로,
      데이터 불일치(Cache Coherency) 문제가 생길 수 있음.
    • OS나 하드웨어는 캐시 플러시(cache flush) 같은 처리를 추가해야 한다.
  • 메모리 보호 문제
    • DMA가 잘못된 메모리 영역에 접근하면 시스템이 망가질 수 있다.
    • 그래서 OS는 IOMMU(Input-Output Memory Management Unit) 같은 걸로 DMA의 접근 범위를 제한한다.

 


정리

구분 CPU 사용 특징
기존 방식 데이터 복사에 CPU가 직접 개입 CPU 낭비 많음
DMA 방식 CPU가 개입하지 않음 CPU는 다른 일 가능, 전송은 장치-메모리 간 직접 처리
  • DMA를 하려면 DMA Controller라는 하드웨어가 필요하다. (CPU와 장치 사이를 조율하는 역할)
  • 네트워크 카드, 디스크 컨트롤러, 사운드 카드 같은 데에서 많이 쓴다.