DMA와 Cycle Stealing: CPU 부담을 줄이는 메모리 전송
DMA와 Cycle Stealing의 전송 원리, 버스 중재 방식, 전송 모드와 IOMMU·RDMA 활용까지 정리한다.
2026-08-14 · 최초 발행 2026-01-06
CPU가 옮기지 않아도 되는 데이터를 어떻게 처리할까
DMA(Direct Memory Access)는 주변 장치가 CPU를 거치지 않고 메모리와 직접 데이터를 주고받도록 하는 방식이다. CPU는 전송의 출발 조건을 설정하고 완료 통지를 받지만, 실제 블록 전송은 DMA 컨트롤러가 맡는다.
Cycle Stealing은 이 전송을 버스 사용 단위로 잘게 나눈다. CPU가 버스를 쓰지 않는 짧은 구간에 DMA가 버스를 확보해 데이터를 옮긴 뒤 곧바로 반환한다. I/O 전송과 CPU 작업을 병행해야 할 때 쓰이는 이유다.
DMA는 다음 기능을 바탕으로 동작한다.
- 주변 장치의 메모리 직접 접근
- DMA 컨트롤러의 버스 제어권 획득
- 설정 뒤 자동 블록 전송
- 전송 완료 시 인터럽트 통지
- 여러 장치를 지원하는 다중 채널
DMA 전송은 설정과 버스 중재를 거친다
DMA 컨트롤러는 메모리 주소, 전송할 바이트 수, 전송 방향과 모드를 보관한다. CPU가 이 정보를 설정하면 DMA는 버스를 요청하고, 중재가 승인될 때마다 전송을 진행한다. 카운터가 소진되면 CPU에 인터럽트를 발생시켜 후처리를 넘긴다.
DMA 컨트롤러(DMAC) 외에 주소 레지스터, 카운트 레지스터, 제어 레지스터, 버스 중재 로직이 이 과정에 관여한다.
Cycle Stealing은 버스를 짧게 빌려 쓴다
Cycle Stealing에서는 DMA가 한 번에 하나의 워드만 전송한다. CPU가 버스를 사용하지 않는 사이클을 활용한 뒤 버스를 돌려주므로, CPU는 1~2 클럭만 정지한다. 전송이 끝날 때까지 이 과정이 반복된다.
CPU가 메모리에 접근하지 않는 메모리 사이클, I/O 명령 실행 중인 I/O 사이클, 캐시 히트로 버스가 필요 없는 구간, 내부 실행 중인 인스트럭션 페치 구간, 데이터 의존성으로 인한 파이프라인 스톨 시간이 DMA에 활용될 수 있다.
전송 모드는 CPU 점유 방식이 다르다
Burst Mode는 DMA가 버스를 완전히 점유한 상태에서 연속 전송한다. 전송 속도는 가장 높지만 CPU는 완전히 정지한다.
Cycle Stealing Mode는 CPU와 DMA가 버스를 교대로 사용한다. 전송을 시간에 분산할 수 있고, 인터럽트 응답 시간을 보장하며, CPU 캐시 히트 시에는 영향이 없다. CPU 작업을 계속 진행할 수 있다는 점도 이 방식의 특징이다.
Transparent Mode는 CPU가 버스를 사용하지 않는 시간에만 전송한다. CPU 성능에 미치는 영향은 제로지만 전송 속도는 가장 느리며, 비중요 데이터의 배경 전송에 맞는다.
| 전송 방식 | CPU 사용률 | 전송 속도 | 실시간성 | 복잡도 |
|---|---|---|---|---|
| 프로그램 I/O | 100% | 느림 | 나쁨 | 낮음 |
| 인터럽트 I/O | 높음 | 중간 | 중간 | 중간 |
| Cycle Stealing DMA | 5~10% | 빠름 | 좋음 | 높음 |
| Burst DMA | 0% (블로킹) | 매우 빠름 | 나쁨 | 중간 |
DMA는 CPU를 연산에 집중시키고, 버스 대역폭 활용과 I/O·연산 병렬 처리를 가능하게 한다. 반면 CPU와 DMA의 버스 경합, DMA의 캐시 우회에 따른 캐시 일관성, 초기화 코드의 복잡성, DMAC 추가 비용, 잘못된 DMA 설정에 따른 시스템 손상 위험은 함께 고려해야 한다.
대용량 I/O 경로에서 DMA가 맡는 일
디스크 I/O에서는 하드디스크의 대용량 읽기·쓰기, DMA 기반인 NVMe SSD 전송, 다중 디스크를 동시에 다루는 RAID 컨트롤러에서 DMA가 쓰인다. 블록 전송은 수 MB 단위로 연속 처리될 수 있으며, 커맨드 큐잉은 다중 DMA 요청을 관리한다.
네트워크에서는 NIC가 수신 패킷을 메모리에 직접 쓰고, 송신 시에는 메모리에서 직접 읽는다. 이 경로는 제로 카피와 연결된다.
오디오·비디오 장치에서는 사운드 카드의 연속 스트림 재생·녹음, 비디오 캡처의 실시간 프레임 버퍼 전송, GPU의 텍스처·버텍스 데이터 전송, HDMI·DisplayPort 비디오 스트림, 코덱의 압축·해제 데이터 이동에 DMA가 관여한다.
USB 컨트롤러, PCIe 장치, 스캐너, 프린터, 센서 데이터 수집 시스템도 직접 메모리 전송을 사용하는 주변 장치 범주다.
가상 주소와 원격 전송으로 넓어진 DMA
IOMMU(I/O Memory Management Unit)는 DMA용 가상 주소 변환, 권한 검사에 의한 메모리 보호, VM 간 격리를 통한 가상화 지원을 제공한다.
Scatter-Gather DMA는 비연속 메모리의 여러 버퍼를 한 번에 전송한다. 디스크립터 체인으로 전송 목록을 처리해 메모리 복사를 줄이고, 네트워크 프로토콜 헤더 조립에도 활용된다. 리눅스 커널은 SGL(Scatter-Gather List)을 지원한다.
RDMA(Remote DMA)는 네트워크 너머의 메모리 접근을 다룬다. 커널을 우회하는 제로 카피 직접 전송과 마이크로초 단위의 초저지연이 특징이며, InfiniBand는 HPC 네트워크 표준이고 RoCE는 이더넷 기반 RDMA다.
커널에서 DMA 버퍼를 다룰 때
리눅스 커널에서는 일관성 있는 DMA 버퍼를 할당하고, 장치에 매핑한 뒤 전송 레지스터를 설정한다. 전송 후에는 매핑을 해제한다.
// DMA 버퍼 할당 예시
dma_addr_t dma_handle;
void *cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL);
// DMA 매핑
dma_addr_t dma_addr = dma_map_single(dev, cpu_addr, size, DMA_TO_DEVICE);
// 전송 설정
writel(dma_addr, device_reg_addr);
writel(size, device_reg_count);
writel(START, device_reg_ctrl);
// 전송 후 언매핑
dma_unmap_single(dev, dma_addr, size, DMA_TO_DEVICE);
구현 시에는 캐시 일관성, 메모리 정렬의 바운더리 제약, 버퍼 고정을 확인해야 한다. 캐시 일관성은 dma_sync_* 함수와 연결되고, 버퍼 고정은 페이지 잠금을 수반한다.
성능 경로에서는 더블 버퍼링으로 DMA 전송 중 CPU 처리를 이어가고, 링 버퍼로 연속 스트림을 다룰 수 있다. 미리 할당한 DMA 풀의 버퍼 재사용, 완료를 기다리지 않는 비동기 처리, 여러 요청을 묶는 배치 전송도 활용된다.