메모리 맵핑 이해

애플리케이션 명령어가 시스템에서 처리되는 속도는 프로그램 주소 지정 가능 메모리 외부의 데이터를 가져오는 데 필요한 액세스 조작의 수에 비례합니다.

시스템은 이러한 외부 읽기 및 쓰기 조작과 연관된 트랜잭션 오버헤드를 줄이는 2가지 메소드를 제공합니다. 파일 데이터를 프로세스 주소 공간에 맵핑할 수 있습니다. 또한 협업 프로세스에서 공유될 수 있는 익명의 메모리 리젼에 프로세스를 맵핑할 수 있습니다.

메모리 맵핑된 파일에서는 프로세스 주소 공간에 파일 데이터를 직접 통합하여 프로세스가 파일에 액세스하도록 하는 메커니즘을 제공합니다. 맵핑된 파일을 사용하면 readwrite 서브루틴에서 수행된 대로 프로세스 데이터 버퍼에 파일 데이터가 복사될 필요가 없으므로 입출력 데이터 이동을 상당히 줄일 수 있습니다. 둘 이상의 프로세스가 동일한 파일에 맵핑되면, 해당 내용이 프로세스 간에 공유되어 프로세스가 동기화하고 통신할 수 있는 낮은 오버헤드 메커니즘을 제공합니다.

공유 메모리 영역이라고도 하는 맵핑된 메모리 리젼은 프로세스 간에 데이터를 교환하기 위한 대형 풀로 역할을 수행할 수 있습니다. 사용 가능한 서브루틴은 프로세스 간에 잠금 또는 액세스 제어를 제공하지 않습니다. 따라서, 공유 메모리 영역을 사용하는 프로세스는 신호 또는 세마포어 제어 메소드를 설정하여 액세스 충돌을 방지하고 한 프로세스가 다른 프로세스에서 사용 중인 데이터를 변경하지 못하도록 해야 합니다. 공유 메모리 영역은 프로세스 간에 교환될 데이터 양이 메시지와 함께 전송되기에 너무 크거나 다수의 프로세스가 공통 대형 데이터베이스를 유지할 때 가장 유용할 수 있습니다.

시스템은 파일 및 익명의 메모리 리젼을 맵핑하는 2가지 메소드를 제공합니다. 집합적으로 shmat 서비스로 알려진 다음 서브루틴은 일반적으로 프로그램에서 공유 메모리 세그먼트를 작성하고 사용하는 데 사용됩니다.

서브루틴 정의
shmctl 공유 메모리 조작을 제어함
shmget 공유 메모리 세그먼트를 가져오거나 작성함
shmat 프로세스에서 공유 메모리 세그먼트를 접속합니다. 블록 장치를 맵핑하도록 허용하지 않습니다.
shmdt 프로세스에서 공유 메모리 세그먼트를 접속 해제합니다.
엠프로텍트 공유 메모리 세그먼트 내 지정된 주소 범위에 대한 액세스 보호를 수정합니다.
부인 공유 메모리 세그먼트 내의 지정된 주소 범위에서 맵핑을 제거함

Ftok 서브루틴은 shmget 서브루틴이 공유 세그먼트를 생성하는 데 사용하는 키를 제공합니다

집합적으로 mmap 서비스로 알려진 서비스의 두 번째 세트는 공유 메모리 세그먼트를 작성하는 데 사용될 수도 있지만 일반적으로 파일을 맵핑하는 데 사용됩니다.

파일의 mmap()에서 기인하는 메모리의 유효한 모든 조작은 블록 장치의 mmap()에서 기인하는 메모리에 유효합니다. 블록 장치는 블록 인터페이스를 표시하는 장치 드라이버에 대한 액세스를 제공하는 특수 파일입니다. 장치 드라이버에 대한 블록 인터페이스에는 고정된 크기의 블록으로 된 데이터 액세스가 필요합니다. 인터페이스는 일반적으로 데이터 스토리지 장치에 사용됩니다.

mmap 서비스에는 다음 서브루틴이 포함됩니다.

서브루틴 정의
madvise 프로세스의 예상된 페이징 동작을 시스템에 통지함
mincore 메모리 페이지의 존재 여부를 판별함
mmap 가상 메모리에 오브젝트 파일을 맵핑합니다. 한 번에 하나의 프로세스씩 블록 장치를 맵핑하도록 허용합니다.
엠프로텍트 메모리 맵핑의 액세스 보호를 수정함
msync 맵핑된 파일을 해당 기본 스토리지 장치와 동기화함
munmap 맵핑된 메모리 리젼을 맵핑 해제함

Msem_init, msem_lock, msem_unlock, msem_remove, msleepmwakeup 서브루틴은 mmap 서비스를 사용하여 매핑된 프로세스에 대한 액세스 제어 기능을 제공합니다.

메모리 맵핑에 대해 자세히 학습하려면 다음 섹션을 참조하십시오.

shmat과 mmap 비교

shmat 서비스의 경우와 같이, mmap 서비스로 파일을 맵핑하는 데 사용 가능한 프로세스 주소 공간의 부분은 프로세스가 32비트 프로세스 또는 64비트 프로세스인지 여부에 따라 다릅니다. 32비트 프로세스의 경우 매핑에 사용할 수 있는 주소 공간의 일부는 다음 범위의 주소로 구성됩니다0x30000000-0xCFFFFFFF를 추가하여 총 2.5G 바이트의 주소 공간을 확보합니다. 파일 매핑에 사용할 수 있는 주소 공간의 일부는 다음 범위의 주소로 구성됩니다0x30000000-0xCFFFFFFF0xE0000000-0xEFFFFFFF를 사용하여 총 2.75G 바이트의 주소 공간을 확보합니다. AIX® 5.2 이상에서 매우 큰 주소 공간 모델로 실행되는 32비트 프로세스는 매핑에 0x30000000-0xFFFFFFFF 범위를 사용할 수 있으며 총 주소 공간은 최대 3.25GB.

32비트 프로세스 주소 공간 내의 모든 사용 가능한 범위는 고정 위치 및 가변 위치 맵핑 둘 다에 사용 가능합니다. 고정 위치 맵핑은 맵핑이 주소 공간 내의 고정된 위치에 배치되도록 애플리케이션이 지정할 때 발생합니다. 가변 위치 맵핑은 맵핑이 배치되어야 하는 위치를 시스템이 결정하도록 애플리케이션이 지정할 때 발생합니다.

64비트 프로세스의 경우, 프로세스 주소 공간이 포함된 주소 범위의 2개 세트가 mmap 또는 shmat 맵핑에 사용 가능합니다. 첫 번째는 단일 범위로 구성된0x07000000_00000000-0x07FFFFFF_FFFFFFFF는 고정 위치 및 가변 위치 매핑 모두에 사용할 수 있습니다. 두 번째 주소 범위 세트는 고정 위치 매핑에만 사용할 수 있으며 다음과 같은 범위로 구성됩니다0x30000000-0xCFFFFFFF,0xE0000000-0xEFFFFFFF0x10_00000000-0x06FFFFFF_FFFFFFFF. 이 세트의 마지막 범위는 다음과 같이 구성됩니다0x10_00000000-0x06FFFFFF_FFFFFFFF는 시스템 로더가 프로그램 텍스트, 데이터 및 힙을 보유할 수 있도록 제공되므로 고정 위치 매핑에는 사용하지 않는 부분만 사용할 수 있습니다.

mmapshmat 서비스 둘 다 해당 오브젝트에 대한 주소 지정 기능을 공유하도록 복수 프로세스가 동일한 오브젝트 리젼을 맵핑하는 기능을 제공합니다. 그러나, mmap 서브루틴은 상대적으로 제한되지 않은 수의 해당 맵핑을 구축하도록 허용하여 shmat 서브루틴에 의해 제공된 것 이상으로 이 기능을 확장합니다. 이 기능으로 메모리 세그먼트 또는 파일 오브젝트마다 지원된 맵핑의 수가 증가하지만, 다수의 프로세스가 동일한 파일 데이터를 해당 주소 공간으로 맵핑하는 애플리케이션에서는 비효율적임을 알 수 있습니다.

mmap 서브루틴은 오브젝트에 맵핑되는 각 프로세스마다 고유한 오브젝트 주소를 제공합니다. 소프트웨어는 별명으로 알려진 고유한 가상 주소를 각 프로세스에 제공하여 이를 수행합니다. shmat 서브루틴을 통해 프로세스는 맵핑된 오브젝트의 주소를 공유할 수 있습니다.

오브젝트의 제공된 페이지에 대한 기존의 별명 중 하나에만 지정된 시간의 실제 주소 변환이 있으므로 mmap 맵핑 중 하나만 페이지 부재 발생 없이 해당 페이지에 대한 참조를 작성할 수 있습니다. 다른 맵핑(따라서 다른 별명)에 의한 페이지 참조가 있으면 페이지의 기존 실제 주소 변환을 무효화하는 페이지 부재가 발생합니다. 따라서 새로운 변환은 다른 별명으로 구축되어야 합니다. 프로세스는 이러한 여러 변환 간에 페이지를 이동하여 페이지를 공유합니다.

다수의 프로세스가 동일한 파일 데이터를 해당 주소 공간으로 맵핑하는 애플리케이션의 경우, 이 토글링 프로세스는 성능에 역효과를 줄 수 있습니다. 이러한 경우, shmat 서브루틴이 더 효율적인 파일 맵핑 기능을 제공할 수 있습니다.

참고: PowerPC® 프로세서가 탑재된 시스템에서는 동일한 실제 주소에 여러 개의 가상 주소가 존재할 수 있습니다. 실제 주소에는 토글링 없이 여러 프로세스의 여러 유효 주소로 별명이 지정될 수 있습니다. 토글링이 없으므로 성능 저하가 없습니다.

다음 상황에서 shmat 서비스를 사용하십시오.

  • 32비트 애플리케이션의 경우, 11개 이하의 파일이 동시에 맵핑되고 각각은 256MB보다 작습니다.
  • 맵핑 파일이 256MB보다 큰 경우입니다.
  • 관련되지 않은 프로세스(상위-하위 관계 없음) 간에 공유되어야 하는 공유 메모리 리젼을 맵핑하는 경우입니다.
  • 전체 파일을 맵핑하는 경우입니다.

다음 상황에서 mmap을 사용하십시오.

  • 애플리케이션의 이식성이 관계된 경우입니다.
  • 다수의 파일이 동시에 맵핑되었습니다.
  • 파일의 일부분만 맵핑되어야 합니다.
  • 페이지 레벨 보호가 맵핑에 설정되어야 합니다.
  • 개인용 맵핑이 필요합니다.

"확장된 shmat" 기능은 주소 공간이 제한된 32비트 애플리케이션에서 사용 가능합니다. 환경 변수 EXTSHM=ON을 정의하면 해당 환경에서 실행되는 프로세스가 11개 보다 많은 공유 메모리 세그먼트를 작성하고 접속할 수 있습니다. 프로세스는 세그먼트의 크기에 대해 주소 공간에 이러한 세그먼트를 접속할 수 있습니다. 다른 세그먼트는 동일한 256M바이트 리젼에서 첫 번째 세그먼트의 끝에 접속될 수 있습니다. 프로세스가 접속할 수 있는 주소는 페이지 경계에 있으며, 이는 SHMLBA_EXTSHM바이트의 배수입니다.

확장된 shmat 기능을 사용하는 데 일부 제한사항이 있습니다. 이러한 공유 메모리 리젼은 인터럽트 처리기에서 버퍼가 고정 해제되는 경우 입출력 버퍼로 사용할 수 없습니다. 확장된 shmat 입출력 버퍼 사용에 대한 제한사항은 mmap 버퍼의 경우와 동일합니다.

환경 변수에서는 EXTSHM=ON인 경우 11개보다 많은 세그먼트를 접속하는 추가 기능 또는 환경 변수가 설정되지 않은 경우 11개 이하의 세그먼트에 대한 고성능 액세스와 함께 애플리케이션을 실행하는 옵션을 제공합니다. 다시 말해서, "확장된 shmat" 기능만 32비트 프로세스에 적용됩니다.

mmap 호환성 고려사항

mmap 서비스는 다양한 표준에 의해 지정되며 기타 운영 체제 구현에서 선택된 파일 맵핑 인터페이스로 공통적으로 사용됩니다. 그러나, mmap 서브루틴의 시스템 구현은 기타 구현과 다를 수 있습니다. mmap 서브루틴은 다음 수정사항을 통합니다.

  • 프로세스 사설 영역으로의 맵핑은 지원되지 않습니다.
  • 맵핑은 내재적으로 맵핑 해제되지 않습니다. MAP_FIXED를 지정하는 mmap 조작은 지정된 범위 내에 맵핑이 이미 있는 경우 실패합니다.
  • 사설 맵핑의 경우, 원본 이전 사본 시맨틱이 첫 번째 쓰기 참조에 대한 페이지 사본을 작성합니다.
  • 입출력 또는 장치 메모리의 맵핑은 지원되지 않습니다.
  • 문자 장치에 대해 읽기-쓰기 조작의 버퍼로 mmap 리젼을 사용하거나 문자 장치를 맵핑하는 것은 지원되지 않습니다.
  • madvise 서브루틴은 호환용으로만 제공됩니다. 시스템은 지정된 통지에 대해 조치를 수행하지 않습니다.
  • mprotect 서브루틴을 사용하면 지정된 리젼이 맵핑 해제된 페이지를 포함할 수 있습니다. 조작 시, 맵핑 해제된 페이지는 간단히 생략됩니다.
  • 정확한 디폴트 맵핑과 MAP_INHERIT, MAP_HASSEMAPHOREMAP_UNALIGNED 플래그에 대한 OSF/AES 특정 옵션은 지원되지 않습니다.

세마포어 서브루틴 사용

Msem_init, msem_lock, msem_unlock, msem_remove, msleepmwakeup 서브루틴은 OSF 애플리케이션 환경 사양을 준수합니다. 세미젯세미옵 서브루틴과 같은 IPC 인터페이스에 대한 대안을 제공합니다. 세마포어를 사용하면 직렬화 메소드가 효율적이고 세마포어에 대해 경합이 없는 경우 시스템 호출을 수행할 필요가 없으므로 오버헤드가 줄어드는 장점이 있습니다.

세마포어는 공유 메모리 리젼에 있어야 합니다. 세마포어는 msemaphore 구조로 지정됩니다. msemaphore 구조의 모든 값은 msem_init 서브루틴 호출에서 발생해야 합니다. 이 호출은 msem_lock 서브루틴 또는 msem_unlock 서브루틴에 대한 호출의 순서가 뒤따르거나 뒤따르지 않을 수 있습니다. msemaphore 구조 값이 다른 방식으로 발생하는 경우 세마포어 서브루틴의 결과는 정의되어 있지 않습니다.

msemaphore 구조의 주소는 중요합니다. 구조의 주소를 수정하지 않도록 주의해야 합니다. 다른 주소의 msemaphore 구조에서 복사된 값이 구조에 포함된 경우 세마포어 서브루틴의 결과가 정의되어 있지 않습니다.

세마포어 서브루틴은 다수의 프로세스가 동일한 세마포어를 참조하는 경우 특히, mmap 서브루틴으로 작성된 익명의 메모리 리젼에 세마포어 구조가 있으면 덜 효율적일 수 있습니다. 이러한 경우, 세마포어 구조는 shmgetshmat 서브루틴으로 작성된 공유 메모리 리젼에서 할당되어야 합니다.

shmat 서브루틴으로 파일 맵핑

맵핑은 파일 내용의 읽기 및 쓰기와 관련된 오버헤드를 줄이는 데 사용될 수 있습니다. 파일의 내용이 사용자 메모리의 영역에 맵핑되면, 입출력 호출 대신 해당 데이터에 대한 포인터를 사용하여 메모리의 데이터와 같이 파일을 조작할 수 있습니다. 또한 디스크의 파일 사본은 해당 파일의 페이징 영역 역할도 하므로, 페이징 공간이 절약됩니다.

프로그램이 모든 일반 파일을 맵핑된 데이터 파일로 사용할 수 있습니다. 또한 맵핑된 데이터 파일의 기능을 컴파일되고 실행 가능한 오브젝트 코드가 포함된 파일로 확장할 수 있습니다. 맵핑된 파일은 일반 파일보다 더 빨리 액세스될 수 있으므로, 실행 가능한 해당 오브젝트 파일이 파일에 맵핑된 경우 시스템이 더 빨리 프로그램을 로드할 수 있습니다.

프로그램을 맵핑된 실행 파일로 작성하려면 -K 플래그를 cc 또는 ld 명령과 함께 사용하여 프로그램을 컴파일하고 링크하십시오. -K 플래그는 링커가 페이지 맞춤 형식으로 오브젝트 파일을 작성하도록 지시합니다. 즉, 오브젝트 파일의 각 부분이 페이지 경계에서 시작됩니다(나머지 없이 2K바이트로 나뉠 수 있는 주소). 이 옵션으로 인해 오브젝트 파일에 일부 빈 공간이 발생하지만 실행 파일을 메모리에 맵핑할 수 있습니다. 시스템이 오브젝트 파일을 메모리에 맵핑할 때 텍스트 및 데이터 부분은 다르게 처리됩니다.

원본 이전 사본 맵핑된 파일

맵핑된 파일의 변경사항이 디스크의 파일에 즉시 나타나지 않도록 하려면 파일을 원본 이전 사본 파일로 맵핑하십시오. 이 옵션은 디스크의 파일 사본 대신 시스템 페이징 공간에 저장되는 변경사항과 함께 맵핑된 파일을 작성합니다. 변경사항을 저장하려면 디스크의 사본에 해당 변경사항을 쓰도록 선택해야 합니다. 그렇지 않으면, 파일을 닫을 때 변경사항이 유실됩니다.

기타 사용자가 액세스할 수 있는 파일 사본에서 변경사항이 즉시 반영되지 않으므로, 서로 협업하는 프로세스 간에만 원본 이전 사본 맵핑된 파일을 사용하십시오.

시스템은 shmat 서브루틴으로 맵핑된 파일의 끝을 발견하지 못합니다. 따라서, 프로그램이 해당 메모리 세그먼트(파일이 맵핑된 경우)에 저장하여 원본 이전 사본 맵핑된 파일에서 파일의 현재 끝을 초과하여 쓰는 경우, 디스크의 실제 파일이 새로운 데이터를 준비할 때 0의 블록으로 확장됩니다. 프로그램이 파일을 닫기 전에 fsync 하위 루틴을 사용하지 않으면 파일의 이전 끝 부분 이후에 쓰여진 데이터는 디스크에 기록되지 않습니다. 파일이 더 크게 나타나지만, 추가된 0만 포함합니다. 따라서 항상 모든 추가되거나 변경된 데이터를 보존하기 위해 원본 이전 사본 맵핑된 파일을 닫기 전에 fsync 서브루틴을 사용하십시오.

shmat 서브루틴으로 공유 메모리 세그먼트 맵핑

시스템은 파일을 작성하고 사용하는 방법과 유사하게 공유 메모리 세그먼트를 사용합니다. 더 친숙한 파일-시스템 항목과 관련하여 공유 메모리에 사용된 항목을 정의하는 것은 공유 메모리를 이해하는 데 중요합니다. 공유 메모리 항목의 정의 리스트는 다음과 같습니다.

기간 정의
특정한 공유 세그먼트의 고유한 ID입니다. 이는 공유 세그먼트가 존재하는 한 공유 세그먼트와 연관됩니다. 이런 점에서, 파일의 파일 이름과 유사합니다.
shmid 특정한 프로세스 내에서 사용하도록 공유 세그먼트에 지정된 ID입니다. 파일의 파일 설명자와 사용 방식이 유사합니다.
첨부 프로세스가 공유 세그먼트를 사용하기 위해 이를 접속하도록 지정합니다. 공유 세그먼트 접속은 파일 열기와 유사합니다.
detach 프로세스가 공유 세그먼트 사용을 완료하면 이를 접속 해제하도록 지정합니다. 공유 세그먼트 접속 해제는 파일 닫기와 유사합니다.