이 프로그램에는 몇 개의 페이지 폴트가 필요합니까?

이 프로그램에는 몇 개의 페이지 폴트가 필요합니까?

운영 체제 개념

인위적이지만 유익한 예를 살펴보겠습니다. 페이지 크기가 128단어라고 가정합니다. 128×128 배열의 각 요소를 0으로 초기화하는 기능을 가진 C 프로그램을 생각해 보세요. 다음 코드가 일반적입니다.

int i, j;
int[128][128] data;
for (j = 0; j < 128; j++)
for (i = 0; i < 128; i++)
data[i][j] = 0;

배열은 행 주 번호를 저장합니다. 즉, 배열은 data[0][0],data[0][1],····,data[0][127],data[1]을 저장합니다. [0],데이터[1][1],····,데이터[127][127]. 128단어 페이지의 경우 각 줄은 한 페이지를 차지합니다. 따라서 이전 코드는 각 페이지에서 한 단어를 0으로 만든 다음 각 페이지의 다른 단어를 0으로 만드는 식입니다.운영 체제가 전체 프로그램에 대해 128개 미만의 프레임을 할당하는 경우 실행 시 128 × 128 = 16,384개의 페이지 오류가 발생합니다.

강조표시된 이 문장은 배열의 각 요소가 초기화될 때 페이지 오류가 발생하고 페이지가 교체되고 요소가 초기화된 직후 페이지가 RAM에서 이동된다는 의미입니까?

"운영 체제는 전체 프로그램에 대해 128개 미만의 프레임을 할당합니다"라고 해서 반드시 "운영 체제가 전체 프로그램에 대해 단일 프레임을 할당합니다"라는 의미는 아닙니다. 그렇다면 텍스트에 액세스하자마자 가장 최근 페이지가 RAM 밖으로 이동될 만큼 확실한 이유는 무엇일까요?

운영 체제가 프로그램에 "n"개의 프레임(128개 미만)을 할당한다고 가정합니다. RAM에 "n-1" 페이지(즉, 행)만 유지하고 나머지 페이지를 사용하여 모든 페이지 오류 및 대체를 처리할 수 있습니까? 그러면 총 페이지 폴트 수는 128*128에서 (n-1) + (128-(n-1))*128로 줄어들 수 있습니까?

답변1

그렇다면 텍스트에 액세스하자마자 가장 최근 페이지가 RAM 밖으로 이동될 만큼 확실한 이유는 무엇일까요?

일반적으로 가장 최근에 방문한 페이지가 제거되지만 이는 설명된 병리학적 동작으로 이어집니다. 내부 루프를 통해 처음으로, 처음으로N프레임이 페이징된 다음 페이지가 호출됩니다.n+1페이지 매김이 필요합니다. 페이지1호출되는 등의 방식으로 순환될 때마다 모든 페이지를 다시 호출해야 합니다.

그러나 이 시나리오는진짜너무 가능하지 않습니다. 시스템에 RAM(물리적 및 스왑)이 완전히 부족한 경우 커널은 테스트 프로그램의 동작을 고려할 때 일부 메모리를 확보하기 위해 프로그램을 종료하므로 가능성이 낮습니다. 시스템에 단순히 물리적 RAM이 부족한 경우 커널은 페이지를 교환하거나 페이지를 교환하는 경우 캐시를 줄이므로 테스트 프로그램을 대상으로 할 가능성이 줄어듭니다. 두 경우 모두 테스트 프로그램에는 작업 세트에 맞는 충분한 RAM이 있습니다. 테스트 프로그램만 굶어 죽게 된다면(예를 들어시스템 메모리를 차지하도록 작업 세트를 늘리면 실제로는 SIGSEGV작업 세트가 지속적으로 페이징 인/아웃되는 것을 보는 것보다 오류로 인해 종료되는 것을 볼 가능성이 더 높습니다. (괜찮습니다. 이것은 교과서적인 사고 실험입니다. 예제를 실제로 적용하려고 하지 않고도 결과 원리를 배우십시오.)

RAM에 "n-1" 페이지(즉, 행)만 유지하고 나머지 페이지를 사용하여 모든 페이지 오류 및 대체를 처리할 수 있습니까?

그것할 수 있다, 그러나 시스템이 이를 수행하는 것은 드문 일입니다. 시스템은 향후 메모리 액세스 패턴이 어떻게 나타날지 어떻게 알 수 있습니까? 일반적으로 LRU 제거가 표시되므로 루프는 위에서 설명한 대로 병리학적 동작을 나타냅니다.

시도해 보고 싶다면 페이지의 4KB 크기와 일치하도록 프로그램을 수정하고(x86에서 사용하기 위해, 여기에서는 Linux가 64비트 x86이라고 가정함) 실제로 컴파일하십시오.

int main(int argc, char **argv) {
  int i, j;
  int data[128][1024];
  for (j = 0; j < 1024; j++)
    for (i = 0; i < 128; i++)
      data[i][j] = 0;
}

그런 다음 다음을 사용하여 실행하십시오 /usr/bin/time. 그러면 페이지 폴트 수가 표시됩니다.

0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 1612maxresident)k
0inputs+0outputs (0major+180minor)pagefaults 0swaps

실제로 이 배열 처리는 페이지 오류보다 캐시 라인 제거 문제를 더 많이 발생시킵니다.

관련 정보