Numbers Everyone Should Know
이러한 숫자를 이해하면 특히 데이터에 액세스하거나 조작해야 하는 작업을 처리할 때 소프트웨어 설계에 대한 선택에 도움이 될 수 있다.
2020년 기준
L1 cache reference | 1 ns | |
Branch mispredict | 3 ns | |
L2 cache reference | 4 ns | |
Mutex lock/unlock | 17 ns | |
Main memory reference | 100 ns | |
Compress 1K bytes with Zippy | 2,000 ns | 2 μs |
Read 1 MB sequentially from memory | 3,000 ns | 3 μs |
SSD random read | 16,000 ns | 16 μs |
Round trip within same datacenter | 500,000 ns | 500 μs |
Read 1 MB sequentially from disk | 825,000 ns | 825 μs |
Disk seek | 2,000,000 ns | 2 ms |
Send packet CA->Netherlands->CA | 150,000,000 ns | 150 ms |
How long to generate image results page (30 thumbnails)?
이미지 썸네일 30개가 있는 웹페이지를 생성하는 경우 처리하는 속도를 계산해보자. (컴퓨터 이미지 읽기 속도 100MB/s라고 가정)
Design 1: Read serially, thumbnail 256K images on the fly
이 프로세스는 순차적으로 데이터를 검색하고 256K 이미지 썸네일을 읽는 작업 과정으로 약 136.8ms가 소요된다.
- 30 seeks * 2 ms/seek + 30 * 256K / 100 MB/s = 136.8 ms
여기서 병목 현상은 디스크 검색과 디스크에서 데이터를 읽는 데 걸리는 시간이다.
Design 2: Issue reads in parallel
병렬 읽기를 구현하면 썸네일 생성에 필요한 시간을 크게 줄일 수 있다.
- 2 ms/seek + 256K read / 100 MB/s = 4.56 ms (다른 변수들은 고려하지 않음)
이는 네트워크 지연과 같은 다른 요인을 고려하지 않은 수치이지만 병렬 처리의 힘을 느낄 수 있다. (단일 이미지 또는 전체 썸네일 셋 캐싱 및 썸네일과 사전 계산과 같은 전략을 포함하여 이러한 설계에는 여러 가지 변형이 있다.) 이 Design1, Design2와 같은 간단한 비교로도 설계 능력이 소프트웨어의 성능에 얼마나 큰 영향을 미치는지 잘 보여준다.
Design for Low Latency
Jeff는 지연 시간을 낮추기 위한 설계가 매우 중요하다고 말한다. 평균 시간을 낮추는 것뿐만 아니라 P90 및 P99 시간도 마찬가지로 중요하다. 사용자 만족도는 일관된 성능에 달려 있기 때문이다.
지연 시간을 개선하는 방법
- 캐싱을 효과적으로 사용하고 인터랙티브한 요청에 더 높은 우선순위를 부여하는 것이다.
- 두 번째로 중요한 요소는 병렬 처리이다. 최신 컴퓨터에서 점점 더 표준이 되고 있는 다중 코어의 성능을 활용하면 처리량과 지연 시간을 모두 크게 개선할 수 있다.
Threads
멀티코어 머신이 확산됨에 따라 스레딩의 중요성이 점점 더 커지고 있다. 스레드를 사용하지 않는다면 컴퓨터의 잠재력을 충분히 활용하지 못하는 것이다. 멀티 스레드 프로그래밍은 어렵게 느껴질 수 있지만 처음부터 스레드를 고려하면 훨씬 더 쉽게 컨트롤할 수 있다. 멀티 쓰레딩은 처리량과 지연 시간 모두에서 윈윈 구조이다. 다만, race condition은 주의해야 한다.
Data Access, RPCs, and Encoding
데이터 액세스 패턴을 이해하는 것은 중요하다. 디스크 읽기든 메모리 참조든, 이러한 측면을 파악하면 보다 효율적인 시스템을 구축하는 데 도움이 된다. 마찬가지로 원격 프로시저 호출(RPC)의 경우, 송수신하는 데이터의 양과 네트워크에 미치는 영향을 파악해야 한다.
데이터를 효과적으로 인코딩하는 것도 또 다른 중요한 포인트이다. CPU는 빠른 반면 메모리와 대역폭은 귀한 자원이므로 가능한 경우 가변 길이 인코딩, 압축, 압축된 인메모리 표현들을 사용하는 것이 좋다.
예를 들어 가변 길이 인코딩을 사용하여 애플리케이션에서 정수를 표현한다고 가정해 보자. 가변 길이 인코딩은 더 적은 바이트를 사용하여 더 작은 숫자를 위한 공간을 절약할 수 있으며, 대부분의 정수가 상대적으로 작은 경우 특히 유용할 수 있다.
또한 대량의 데이터를 처리하는 애플리케이션의 경우 Zippy와 같은 데이터 압축 알고리즘을 구현하는 것이 유용할 수 있다. 이러한 기술은 데이터의 크기를 줄여 디스크에 데이터를 읽거나 쓰거나 네트워크를 통해 전송하는 데 필요한 시간을 줄이는 데 도움이 된다. 압축된 인메모리 표현은 데이터에 액세스하는 시간을 더욱 단축하여 전반적인 성능을 향상시킬 수 있다.
분산 시스템에서는 원격 프로시저 호출(RPC)과 관련된 지연 시간을 이해하는 것이 매우 중요하다. 데이터 센터 내 왕복 시간(Round trip within same datacenter)은 최대 500μs에 달할 수 있으며, 이는 로컬 작업보다 훨씬 더 큰 규모이다. 따라서 각 호출에서 전송되는 데이터의 양을 최적화하고 RPC의 수를 줄이면 전체 지연 시간을 줄이는 데 도움이 될 수 있다.
Refs
http://brenocon.com/dean_perf.html
https://gist.github.com/jboner/2841832
https://colin-scott.github.io/personal_website/research/interactive_latency.html
'Dot . > 개인 공부 기록용' 카테고리의 다른 글
트위터 추천 알고리즘 RealGraph 정리 How does Twitter Recommend "For You" Timeline? (0) | 2023.04.27 |
---|---|
GIT 사용할 때 협업시 미리 알고 있으면 좋은 명령어 (0) | 2022.07.24 |
nGrinder vs Jmeter 성능 테스트 툴 비교해보기 (0) | 2022.04.29 |
코드 리뷰 피라미드 (0) | 2022.04.13 |
배포한 프로젝트 서버 성능 올리기 (처리량, 응답시간) (0) | 2022.04.03 |