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
이 문제를 해결했습니다.
- 내 코드의 주요 문제점 중 하나는 malloc 페이지가 처음 작성될 때 Linux가 디스크에서 빈 페이지를 읽을 필요가 없기 때문에 페이지 폴트가 발생하지 않는다는 것입니다. 코드의 루프 부분을 두 번 실행하도록 코드를 변경했습니다.
- 또한 Linux 미리 읽기를 비활성화했습니다(echo "0" >> /proc/sys/vm/page-cluster를 통해).
이 두 가지 변경으로 약 2G/4K = 524,288개의 페이지 폴트(정확히는 524,304개)를 볼 수 있었습니다.
답변2
모든 페이지가 처음으로 메모리에 기록될 때 페이지 오류가 발생하는 이유는 무엇입니까? 이는 가상 메모리 하위 시스템에 있어서 최악의 결과입니다. 따라서 최적화, 캐싱, 사전 로드, 액세스 패턴 감지 등으로 인해 이 숫자가 줄어듭니다. 이것을 시도해 보면 어떤 운영 체제라도 계산된 256,000개의 페이지 오류를 안정적으로 제공할 수 있다면 놀랄 것입니다.
답변3
최적화를 활성화하고 컴파일러를 사용하여 컴파일했습니다.루프를 삭제했습니다, 소름 끼치는 장군전체 프로그램을:
int main() {
while(1);
}