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 코어를 완전히 점유하는 비용이 따름
저자는 본문에서 다룬 주요 주제들을 요약: 제로 복사 작업, 링 버퍼, 페이징 & 가상 메모리, 동기화 오버헤드
저자는 또한 본문에서 논의되지 않은 많은 다른 옵션과 세부 사항들이 있음을 인정, 이는 그들의 관련성이 없거나 관심이 부족하기 때문