[t:/]$ 지식_

mmap 이모저모

2018/04/17

커널 업무를 놓은 관계로 커널 소스를 까봐야 정확할텐데... 거기까진 포기한다. 우분투인데 뭔 커널 버전이 벌써 4.15여... 헐..

+) 수정필요 : 막상 프로파일링 해보니 조금 틀린 곳이 있네요. 나중에 고칩니다. 이 글을 참조로 삼지 마세요.

1.

순차 읽기에 있어서 MAP_POPULATE를 쓰라고 한다. 페이지 폴트를 막기 위해 미리 읽기를 시도한다고 맨페이지에 써 있다. TLB 미스를 확인하진 않았으나 쓰나 안 쓰나 비슷한 결과가 나왔는데 실험 조건이 잘못된 것은 아닐까. 닥치고 쓴다.

2.

madvice로 page-fault를 덜 유발할 수 있다. MADV_SEQUENTIAL | MADV_WILLNEED 를 쓰라고 한다. 일단 동일 조건에서는 MAP_POPULATE를 쓰면 이게 자동으로 먹는 건 아닐까. 닥치고 쓰는 것이 좋겠다.

3.

같은 fd로 중복 mmap해도 된다. 중복 mmap 할 때 fd의 offset을 꼬아가지고 와서 읽고 뭐 그러지 않을까 걱정을 해봤다. 멀티쓰레드나 멀티프로세스라면 꼬이지 않을까? 아직 실험은 안 해봤다. 순차 mmap이라면 문제 없었다. 쓰레드를 버스트하게 생성하면서 생성된 쓰레드들이 동시다발적으로 같은 fd를 이용해 서로 다른 offset으로 mmap을 시도한다면 문제가 될지도 모른다.

4.

fd를 dup해서 써도 되고, fd마다 open을 새로 쳐도 써도 속도는 비슷하다. 그게 그거. 그런데 dup은 offset을 공유하므로 앞에서 말한 멀티쓰레드 걱정이 좀 있다. fd마다 open해서 mmap을 바로 수행하는 것이 안전할 것 같은데 오바인가?

5.

큰 파일을 나눠서 mmap하는 것이 확실히 빠르긴 빠르다는 것이다. 그런데 망할 4096 단위 얼라인 맞춰서 산수 하는 것이 영 귀찮다. 속편하게 하는 방법은 4096 단위로만 작업하고 마지막 짜투리만 패딩으로 연산하는 것이다. 단위 슬라이스마다 4096 패딩 처리를 하려면 영 산수가 골때려진다.

6.

해석하면 이렇다. 큰 파일을 통 mmap으로 잡고 멀티쓰레드가 각각 나눠 읽는 상황이다. 이때 각각의 멀티쓰레드는 운빨이 따라 느린 놈과 빠른 놈이 생긴다. 커널은 page-fault를 막기 위해 미리 읽기 한다고 노력하는데, 멀티쓰레드로 나눠놨으니 다른 쓰레드에서 저 멀리 있는 페이지를 읽는다고 쑈를 한다. 커널의 미리 읽기 예측이 틀어질 가능성이 생기는 것이다. 캐시 미스 방지하고 페이지 폴트를 줄이기 위해 로켈리티를 보장하도록 짰다고 해도 마찬가지인데, 멀티쓰레드로 나눈이상 빠른 놈이 치고 나가 더 꼬리쪽의 주소를 접근하고 느린 놈이 더 머리쪽의 주소를 접근하면서 이 갭이 벌어지면 L3 입장에서는 캐시에서 나가버릴 확률이 높을 것 같고, 페이징 입장에서는 페이지 폴트를 막기 위한 미리 읽기가 틀어질 수 있겠다. 앞뒤앞뒤앞뒤... L2 입장에서는 로캘리티 아다리가 맞을 확률이 높으므로 괜찮을 수 있겠는데 잘은 모르겠다.









[t:/] is not "technology - root". dawnsea, rss