테크레시피

프로그램 파일 읽고 쓰기, mmap 쓰면 빨라지는 이유

소프트웨어 개발에서 파일 읽고 쓰기는 사용 빈도가 높은 작업이며 속도 향상은 소프트웨어 전체 성능에 크게 영향을 준다. 이런 파일을 읽고 쓰는 작업을 할 때 mmap를 사용하는 게 보통 시스템 호출보다 빠르게 파일을 조작할 수 있는 이유는 뭘까.

운영체제에서 사용자가 프로그램을 실행할 때 프로그램은 사용자 공간과 커널 공간이라는 2가지 영역을 이용한다. 사용자 공간은 프로그램이 자유롭게 액세스할 수 있지만 커널 공간은 프로그램에서 직접 액세스할 수 없다. 자원 공간을 2개로 분리하는 건 보안 측면에서 뛰어나지만 파일 읽고 쓰기 등 하드웨어 작업을 수반하는 처리는 커널 공간 밖에 할 수 없기 때문에 사용자가 커널 공간을 취급할 수 없는 건 불편하다.

이런 이유로 사용자가 커널 공간을 취급할 수 있도록 사용자 공간과 커널 공간 가교 역할을 해주는 게 시스템 호출이다. 예를 들어 파일을 가져올 경우 오픈(Open) 시스템 호출을 사용해 파일 입출력을 위한 파일 디스크립터를 만들고 읽기(read) 시스템 콜을 호출하고 파일 디스크립터 파일 데이터를 버퍼에 읽어 데이터 조작을 가능하게 한다.

운영체제에서 파일 작업을 할 때 일반적 절차지만 파일 읽고 쓰기는 mmap 시스템 호출도 가능하다. mmap 파일을 운영체제 가상 메모리에 맵핑할 수 있는 시스템 호출에서 맵핑된 가상 메모리 주소에서 파일을 읽고 쓸 수 있기 때문에 다른 시스템 호출을 사용할 필요가 없어진다는 것.

일반 시스템 호출을 사용하는 경우와 mmap를 이용한 경우에는 파일 작업 속도를 비교하기 위해 각각 경우에 있어 순차 읽기와 랜덤 읽기 속도를 4KB, 8KB, 16KB 블록 크기 측정이라는 것. 실제로 데이터가 버퍼 캐시에 존재하는 경우 순차 읽기 속도 측정 결과에서 mmap 로딩 속도가 더 빠르다.

랜덤 읽기 속도도 연속 읽기 경우와 같이 mmap로 읽기 속도가 일반 시스템 호출 로딩 속도를 웃돈다. 16KB 블록 크기에서 순차 읽기를 실시했을 때 CPU 사용량도 데이터를 커널 공간에서 사용자 공간에 복사(copy_user_enhanced_fast_string)하는데 걸린 시간은 전체 프로그램 실행 시간 중 61%를 차지하고 있다는 걸 알 수 있다. 그 밖에도 다른 커널 공간(functions do_syscall_64, entry_SYSCALL_64)에서 사용자 공간에 이동을 수반한 명령에 15% 시간을 할애하고 있다. mmap를 이용하면 61%가 ‘__memmove_avx_unaligned_erms’에 소요된다. 다시 말해 통상적 시스템 호출에 의한 처리 대부분을 차지하는 부분(copy_user_enhanced_fast_string)과 mmap로 처리를 많이 차지하는 부분(__memmove_avx_unaligned_erms)간 효율성 차이는 읽기 속도 차이에 크게 영향을 준다고 말할 수 있다.

양자간 효율성 차이는 데이터를 여러 스트림으로 취급하는 AVX에 대응하고 ‘__memmove_avx_unaligned_erms’는 AVX를 지원하고 메모리 대역폭을 효율적으로 사용할 수 있지만 ‘copy_user_enhanced_fast_string’은 AVX를 대응하지 않아 대역폭을 최대한 이용할 수 없다. 이게 보통 시스템 콜보다 mmap가 더 빠르게 파일 작업을 수행할 수 있는 이유다.

일반 시스템 콜이 AVX를 지원하지 않는 이유는 시스템 호출마다 레지스터 저장과 조작이 발생해 사용자 공간과 커널 공간을 이동하는 처리 부하가 커져 버리기 때문이라는 것이다. 이에 따라 파일 작업을 일반적인 시스템 호출에서 mmap로 대체하는 응용 프로그램을 더 빠르게 작동시킬지 모른다고 밝히고 있다. 관련 내용은 이곳에서 확인할 수 있다.

추천기사