- Unix 파이프의 Linux에서의 구현과 파이프를 통해 데이터를 쓰고 읽는 테스트 프로그램 최적화 방법 탐구
- 초기 프로그램은 약 3.5GiB/s의 처리량을 가졌으며, 다양한 최적화를 통해 이를 20배로 향상
- 이러한 최적화는 Linux의 perf 도구를 사용하여 프로그램을 프로파일링함으로써 이루어짐
- 본문은 ~35GiB/s의 속도로 파이프에 출력을 밀어넣는 최적화된 FizzBuzz 프로그램에 영감을 받음
- 파이프의 내부 작동 방식, 그것들로부터 쓰고 읽는 것이 느린 이유, 그리고 vmsplice와 splice 시스템 호출이 성능을 향상시키는 방법에 대해 깊이 파고듬
- Linux 페이징과 huge pages 사용이 프로그램의 더 빠른 버전으로 이어질 수 있는 방법에 대해 논의
- 최종 최적화는 폴링을 바쁜 루프로 대체하는 것을 포함
- 테스트는 Intel Skylake i7-8550U CPU와 Linux 5.17에서 수행됨
- 본문은 메모리가 일정한 크기의 덩어리인 페이지로 구성되는 방법과 CPU가 페이지 테이블을 사용하여 가상 주소를 물리 주소로 변환하는 방법에 대해 자세히 설명
- 본문은 프로그램에서 huge pages로 전환하면 성능이 약 50% 향상된다는 관찰로 결론
- 본문은 CPU에서 huge pages의 사용과 Translation Lookaside Buffer (TLB) 미스를 줄이는 방법에 대해 논의, 이는 성능을 향상시킬 수 있음
- 커널 코드는 struct page가 현재 아키텍처의 표준 크기 페이지를 가리킨다고 가정. huge pages의 경우, "head" struct page에 실제 물리 페이지에 대한 정보가 포함되며, 연속적인 "tail" 페이지는 head 페이지를 가리키는 포인터만 포함
- 최근 커널(5.17 이후)은 head 페이지를 명시적으로 식별하는 새로운 타입인 struct folio를 포함. 이는 런타임에 struct page가 head 페이지인지 tail 페이지인지 확인하는 필요성을 줄여 성능을 향상시킴
- 본문은 동기화 비용을 회피하기 위한 바쁜 루프 개념에 대해 논의. 이는 파이프에 쓸 수 없는 경우 vmsplice가 반환하도록 요청하고, 준비될 때까지 바쁜 루프를 돌게 함. 이는 25%의 성능 향상을 가져올 수 있지만, vmsplice가 준비될 때까지 CPU 코어를 완전히 점유하는 비용이 따름
- 저자는 본문에서 다룬 주요 주제들을 요약: 제로 복사 작업, 링 버퍼, 페이징 & 가상 메모리, 동기화 오버헤드
- 저자는 또한 본문에서 논의되지 않은 많은 다른 옵션과 세부 사항들이 있음을 인정, 이는 그들의 관련성이 없거나 관심이 부족하기 때문
- 본문은 독자들로부터 잘 받아들여짐, 이는 그들에게 도움이 되고 흥미롭다고 발견되었기 때문