Kernel Prefetching Size

최승혁·2023년 3월 29일
0

커널이 prefetching 하는 page의 수를 어떻게 결정하는 지 알아보자.

관련 개념
#page_cluster #disk_I/O #page fault #prefetching

1. Kernel Prefetching

커널이 prefetching을 동작할 때, prefetching page 수를 어떻게 정하는가?


  • swapin_readahead()

아래는 kernel 4.15.18 버전의 swapin_readahead() 함수이다.

커널의 prefetching을 동작하는 함수는 swapin_readahead()이다. 이 함수에서는 fault page의 swap entry를 매개변수로 받고 있으며, 이를 기준으로 swap space 내의 offset을 통해 prefetching을 수행하고 있다.

커널의 prefetching은 주로 fault page를 기준으로 좌우로 mask - 1의 크기만큼의 page를 prefetching한다. 이 연산은 함수 내의 다음 부분이다.

start_offset = offset & ~mask;
end_offset = offset | mask;

이는 즉, 비트 연산을 통해 시작 오프셋과 끝 오프셋을 결정하며 크기는 항상 mask - 1값을 가지게 된다. 그리고 이 mask 값은 swapin_nr_pages() 함수를 통해 정해지게 된다.

그리고 여기서 mask의 크기만큼 뒤의 page를 가져오는 것이 아니라 mask를 bit 연산하여 fault page의 오프셋을 기준으로 좌우로 mask개수만큼의 page를 가져오는 것은 바로 캐시 지역성 때문이다. 이전에 수행한 prefetching과 동일한 영역의 page들을 가져옮으로써 캐시 지역성을 높이기 위함이다.


  • swapin_nr_pages()

아래는 커널 4.15.18 버전의 swapin_nr_pages() 함수이다.

swapin_nr_pages() 함수는 현재 fault page의 오프셋과 이전의 fault page의 오프셋, 그리고 prefetching의 hit 수 등을 고려하여 prefetching page 수를 동적으로 정한다.

이 때, max_pagespage_cluster의 크기를 거듭제곱 한 수로 제한하고 있다. 각 커널의 버전마다 이 부분이 다른데, 이는 prefethcing을 얼마나 할 지에 따라 *2를 넣어 사용하기도 한다. 이와 관련된 설명은 아래의 page cluster에 관한 설명을 참조하자.

  • __swapin_nr_pages()

아래는 커널 4.15.18 버전의 __swapin_nr_pages() 함수이다.

prefetching이 얼마나 잘 동작하느냐에 따라 prefetcing 윈도우 크기가 달라지는 알고리즘에 대한 함수이다. 함수는 아래와 같이 동작한다.

  • prefetching이 hit 되지 않을 때
    • 현재 offset을 prev_offset으로 지정한다.
    • prefetching 윈도우 크기를 1로 줄인다.
  • prefetching이 hit 되고 있을 때
    • 2의 거듭제곱 수만큼 prefetching 수를 round up 한다.
  • 만약 크기가 page cluster의 크기를 넘어가면 제한
  • Prefetching 크기가 갑자기 1로 줄어드는 것을 방지하기 위해,
    이전의 prefetching 크기를 저장하였다가 이를 반영

2. Page Cluster

페이지 클러스터 수가 뭔가?

  • 정의

linux-kernel에서 official 정의는 다음과 같다.

page-cluster controls the number of pages up to which consecutive pages are read in from swap in a single attempt. This is the swap counterpart to page cache readahead. The mentioned consecutivity is not in terms of virtual/physical addresses, but consecutive on swap space - that means they were swapped out together.

It is a logarithmic value - setting it to zero means "1 page", setting it to 1 means "2 pages", setting it to 2 means "4 pages", etc. Zero disables swap readahead completely.

The default value is three (eight pages at a time). There may be some small benefits in tuning this to a different value if your workload is swap-intensive.

Lower values mean lower latencies for initial faults, but at the same time extra faults and I/O delays for following faults if they would have been part of that consecutive pages readahead would have brought in.

즉, 페이지 클러스터는 스왑 공간 내에서 페이지를 읽어들여올 때 한 번의 시도로 읽을 수 있는 페이지의 수를 제한하는 수이다.

따라서 한 번의 disk I/O에 페이지 클러스터 크기만큼의 page 수를 가져올 수 있다. 그렇기 때문에 위의 swapin_readahead() 함수에서는 fault page + prefetching page를 가져오기 위해 mask -1의 값을 사용한 것이다.

page_cluster의 값은 sysctl_prefetch_numsysctl_max_prefetch_num 값 중 작은 값을 사용하며, 기본적으로 1과 32로 설정되어 있다.

커널 4.15.18 버전을 기준으로 page_cluster의 값은 3이며 따라서 최대 prefetching page 수는 8이다.

profile
그냥 기록하는 블로그

0개의 댓글