본문 바로가기
컴퓨터공학기초 개념/시스템 프로그래밍

35. 시스템 프로그래밍 - 메모리 & mmap

by devraphy 2021. 9. 27.

1. molloc() - memory allocation 

- molloc()은 C언어에서 동적 메모리 생성을 위해 사용되는 함수다. 

- 동적 할당이란, 개발자가 직접 메모리를 할당한다는 의미이다. 

- 프로세스의 Heap 영역은 동적으로 생성된 메모리가 할당되는 장소다. 

- molloc()을 사용하여 메모리를 동적 할당하는 과정이 어떻게 진행되는지 살펴보자.

 

 

a) 동적 할당과 관련된 함수

▶ molloc() 

   - 동적 할당 메모리를 생성하는 함수

 

▶ free()

   - 동적 할당된 메모리를 해제하는 함수  

 


2. mmap() - memory mapping

a) 파일 처리 성능 개선 기법 - 메모리에 파일을 매핑하기 

- 프로세스에서 파일을 읽을 때, OS의 시스템 콜을 시작으로 저장매체에 접근하여 파일을 읽기 까지의 과정이 복잡하며 오래걸린다. 

- 더불어, 내부적으로 OS가 처리해야하는 과정(시스템콜, 인터럽트, 스케줄링)이 많기 때문에 CPU의 성능이 떨어지기 마련이다. 

- 이처럼 파일에 접근하는 과정의 효율성을 높이기 위해 사용하는 함수가 mmap()이다.  

 

 

b) mmap()의 동작방식

- mmap()은 메모리의 특정 공간에 파일을 매핑한다. 

- 프로세스는 해당 파일을 읽기 위해서 저장매체에 접근하는 것이 아닌, 메모리의 데이터에 접근하는 방식이다.

- 그러므로 시스템 콜, 스케줄링, 인터럽트 등 OS의 개입과 저장매체로의 접근이 필요없다.

- 즉, 성능이 개선된다. 

 

 

c) mmap()의 인자 

#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

▶ *start

   - 매핑할 메모리의 시작주소

   - 일반적으로 NULL 또는 0을 사용한다. 

 

 

▶ length

   - 매핑할 메모리의 길이

 

 

▶ prot

   - 권한 설정

   - PROT_READ(읽기 가능), PROT_WRITE(쓰기 가능), PROT_EXEC(실행 가능), PROT_NONE(접근 불가)

   - 일반적으로 읽기와 쓰기 기능을 사용한다. 

 

 

▶ flags

   - 메모리 주소 공간 설정 

   - 메모리를 어디에 생성할 것인지를 설정한다. 

   - MAP_SHARED(다른 프로세스와 공유가능 / 프로세스 외부 생성)

   - MAP_PRIVATE(프로세스 내에서만 사용 / 프로세스 내부 생성)

   - MAP_FIXED(지정된 주소로 공간지정 / 지정된 공간에 생성)

 

 

▶ fd

   - 어떤 파일을 매핑 시킬 것인지 명시한다.

   - file descriptor를 의미한다.

 

 

▶ offset

   - 시작주소를 기준으로 얼만큼 떨어진 곳에 생성할 건지를 명시한다. 

   - 예를 들어 offset이 10이고 start가 0인 경우, 파일과 매핑되는 메모리는 주소는 10부터 시작한다.

 


3. mmap의 작동과정 총 정리 

- 이 과정을 이해하기 위해서는 기본적으로 운영체제와 가상 메모리에 대한 이해가 필요하다. 

- 기본적으로 이에 대한 지식과 이해를 갖추었다는 것을 전재하에 설명을 진행한다. 

 

1. mmap 실행 후, 가상 메모리 주소에 file 주소가 매핑된다. (현재 사용되고 있는 페이지 테이블에 할당된다.)

 

2. 해당 메모리에 접근할 때, OS가 파일 데이터를 복사하여 물리 메모리에 업로드 된다.

   ▶ Lazy allocation, 요구 페이징 기법

   ▶ 페이지 폴트 인터럽트가 발생

 

3. 메모리 read - 가상 메모리에 매핑되어 있는 물리 메모리의 데이터를 읽는다. (메모리 접근만 실행) 

 

4. 메모리 write - 해당 물리 메모리의 데이터를 수정한 후, 가상 메모리에 매핑된 페이지의 상태를 나타내는 flag를 수정한다.

  ▶ 페이지 상태 flag를 dirty bit를 사용하여 1로 수정한다. 

  ▶ 파일이 종료(close)되면 물리 메모리의 데이터가 file에 업데이트 된다. 이 때, 처음으로 파일에 직접 접근하게 된다. 

 

- 즉, 가상메모리의 페이징 시스템을 통해 파일 데이터를 조작 및 처리하여 저장매체에 접근하는 횟수를 최소화한다. 

- 이와 같은 이유로 파일 처리 과정의 성능 및 효율성이 개선된다. 

 

 

a) mmap()의 장점 

   - read와 write를 반복적으로 실행하는 경우, 파일 접근(저장매체 접근)을 방지하여 속도 및 성능을 개선한다.

   - 파일에 직접적으로 접근하는 경우(저장매체 접근), lseek() 라는 함수를 사용하여 해당 파일의 데이터 주소를 검색한다. 

   - 이 과정에서 물리적인 시간이 오래 걸리는 것인데, 이를 사용하지 않고 메모리를 통해 포인터 조작만으로 파일 탐색이 가능하다. 

 

 

b) mmap()의 단점 

   - mmap()은 가상메모리를 적극적으로 활용하는 함수다. 

   - 만약 가상메모리에서 페이징 시스템을 사용한다면, 각 페이지는 고정된 사이즈의 블럭을 사용한다. 

   - 4KB 단위의 페이지를 사용하는 페이징 시스템이라면,  1Btye의 파일을 매핑하기 위해서 한개의 페이지를 사용하게 된다.

   - 즉, 페이지 단위보다 파일의 사이즈가 크다면 추가공간이 필요하고 파일의 사이즈가 작다면 낭비되는 공간이 발생한다. 

 


4. munmap() - 파일이 매핑된 메모리 해제(memory unmap)

- munmap() 함수는 mmap()으로 파일이 매핑된 메모리 공간을 강제로 해제하는 함수다. 

- 다음 함수의 원문을 보자.

int munmap(void *addr, size_t length);
// *addr: mapping된 물리 메모리의 시작주소 
// length: mapping된 물리 메모리의 길이(mmap에서 지정했던 길이와 동일)

 

- 해당 내용은 다음 포스팅에서 이어입니다. 

댓글