https://gall.dcinside.com/mgallery/board/view/?id=github&no=6099&page=1
다시 요약하자면,
개발한 알고리즘 테스트를 위해 벤치마크를 돌리고 있었음.
벤치마크 관련 설정 json 파일을 쭉 읽은 다음에 파싱하고, 그 다음에 벤치마크의 런타임이 시작됨.
근데 문제는 json 의 길이가 kB 단위냐 MB 단위냐에 따라 벤치마크의 런타임이 크게 영향을 받음.
구체적으로는, 적용된 알고리즘과 무관하게 json 이 MB 정도로 크면 벤치마크가 갑자기 런타임 variation 도 줄어들고 빨라짐.
원래는 page allocation 관련된 이슈라고 생각을 했었음.
MB 단위 string 을 allocation 한 다음에 거기서 json 파싱을 하니까 이 string 의 메모리를 땡겨올 때,
page 를 잔뜩 받아오니까 eviction 이 되지 않는 이상 나중에 다시 page 를 요청하면 빠른게 아니냐는거였음.
perf 로 확인해본 결과 MB 짜리 json 을 읽을 때 page fault 가 거의 20배 가까이 나는 것을 확인했음.
그래서 벤치마크 실행되기 전에 mmap 이용해서 메모리를 잔뜩 받은 다음에 mlock 으로 pinning 을 했음.
그러면 page 를 미리 땡겨오니까 json 의 길이와 무관하게 동일한 조건일 것이라고 생각했는데,
해본 결과 아무런 효과가 없었다!
그래서 에라 모르겠다 하고 2GB 짜리 std::vector 를 생성한 다음에,
4kB 마다 memory write 를 해서 dirty page 로 만드는 무식한 방법으로 해봤는데
놀랍게도 이건 효과가 있었다!
문제는 locked memory 할당 받는거랑 malloc 으로 할당 받는거랑 무슨 차이가 있냐는거지
메모리 쪽 전공자 대학원생분과 곰곰히 대화를 나눠본 결과,
이거는 의외로 OS 의 문제가 아니라 미들웨어의 문제일 것이라고 결론을 내렸음.
glibc 의 malloc 을 사용해서 메모리를 할당 받는데,
malloc 은 독자적으로 page 들을 관리함.
malloc 을 잔뜩 호출할 경우 이 page 들을 미리 caching 하는게 아니냐는 것
정답은 저 너머에..
3줄 요약
1. 메모리를 잔뜩 할당 받았다가 해제하고 나서 벤치마크가 갑자기 빨라짐
2. page allocation 문제라고 추정했으나 아니었음.
3. OS 단 이슈가 아니라 미들웨어의 문제라고 결론 내림.
댓글 0