페이지 부재가 예상한 만큼 많이 표시되지 않는 이유는 무엇입니까?

페이지 부재가 예상한 만큼 많이 표시되지 않는 이유는 무엇입니까?

Linux의 페이지 오류 동작을 탐색하려고 합니다. 메모리를 1GB로 제한하는 lxc 컨테이너를 만들었습니다(/etc/lxc/default.conf에 'lxc.cgroup.memory.limit_in_bytes = 1G'를 추가하여). 그런 다음 간단한 코드를 실행하여 2GB의 데이터에 액세스했습니다.

int main() {
  char* buf = malloc(1024*1024*1024);
  char* buf2 = malloc(1024*1024*1024);
  if (buf == 0 || buf2 == 0) {
    printf("Malloc failed!\n");
    return 0;
  }
  int i,j,k;
  for (i=0; i<1024; i++)
    for (j=0; j<1024; j++)
      for (k=0; k<1024; k++)
        buf[i*1024*1024 + j*1024 + k] = i+j+k;
  for (i=0; i<1024; i++)
    for (j=0; j<1024; j++)
      for (k=0; k<1024; k++)
        buf2[i*1024*1024 + j*1024 + k] = i+j+k;
  free(buf);
  free(buf2);
  while(1);
  return 0;
}

코드는 -O0으로 컴파일되어 컨테이너 내부에서 실행됩니다. 프로그램이 while(1)에 도달하면 얼마나 많은 페이지 오류가 발생했는지 확인합니다.

ps -eo maj_flt,cmd | grep a.out

여기서 a.out은 컴파일된 실행 파일입니다. 때로는 200~300페이지 오류가 표시되기도 하고, 때로는 10~20페이지 오류만 표시되기도 합니다. 메모리가 1G 밖에 안 되기 때문에 적어도 1G/4K = 256K 페이지 폴트는 항상 발생하리라 생각합니다. 가끔 10~20페이지 오류만 표시되는 이유는 무엇입니까? 내 Linux는 기본적으로 4K 페이지를 사용한다는 것을 확인했습니다.

저는 리눅스를 처음 접했습니다. 어떤 통찰력이라도 매우 도움이 될 것입니다! 감사해요.

답변1

이 문제를 해결했습니다.

  1. 내 코드의 주요 문제점 중 하나는 malloc 페이지가 처음 작성될 때 Linux가 디스크에서 빈 페이지를 읽을 필요가 없기 때문에 페이지 폴트가 발생하지 않는다는 것입니다. 코드의 루프 부분을 두 번 실행하도록 코드를 변경했습니다.
  2. 또한 Linux 미리 읽기를 비활성화했습니다(echo "0" >> /proc/sys/vm/page-cluster를 통해).

이 두 가지 변경으로 약 2G/4K = 524,288개의 페이지 폴트(정확히는 524,304개)를 볼 수 있었습니다.

답변2

모든 페이지가 처음으로 메모리에 기록될 때 페이지 오류가 발생하는 이유는 무엇입니까? 이는 가상 메모리 하위 시스템에 있어서 최악의 결과입니다. 따라서 최적화, 캐싱, 사전 로드, 액세스 패턴 감지 등으로 인해 이 숫자가 줄어듭니다. 이것을 시도해 보면 어떤 운영 체제라도 계산된 256,000개의 페이지 오류를 안정적으로 제공할 수 있다면 놀랄 것입니다.

답변3

최적화를 활성화하고 컴파일러를 사용하여 컴파일했습니다.루프를 삭제했습니다, 소름 끼치는 장군전체 프로그램을:

int main() {
  while(1);
}

관련 정보