-
[WWDC24] Swift의 성능 살펴보기 (1 / 3)IOS/WWDC24 2024. 12. 7. 14:26
https://developer.apple.com/wwdc24/10217
Explore Swift performance - WWDC24 - Videos - Apple Developer
Discover how Swift balances abstraction and performance. Learn what elements of performance to consider and how the Swift optimizer...
developer.apple.com
해당 영상에서 Swift 최적화 부분에 표면적으로 드러나는 부분 외 내부적인 최적화를 다루는 내용입니다.
보통 개발자는 표면적으로 바로 볼 수 있는 알고리즘을 수정해서 최적화하는 방법이 있지만 추가적으로 내부적인 최적화도 알고 있어야 한다는 걸 깨달은 영상으로 내용을 정리해서 공유드리려고 합니다.
Low Level Costs 영향받는 요소
1. Function Call
2. Memory allocation
3. Memory Layout
4. Value Copying
1. Function Calls
함수 호출에 연관된 비용은 4가지입니다.
- Allocate space for the function's local state
함수가 호출되면, 함수 내에서 사용할 변수나 상태를 저장할 공간이 필요합니다. 이 단계에서는 메모리에 그 공간을 할당하게 됩니다.
- Allocate space for the function's local state
호출하려는 함수의 실제 주소를 알아야 합니다. Swift는 동적 바인딩을 채택하므로 호출 시점에 정확한 함수 참조가 필요합니다.
- Put the arguments in the right places
함수가 실행되려면 입력으로 전달할 인자들이 올바른 위치에 있어야 합니다. 이 단계에서는 호출된 함수가 인자를 적절히 받을 수 있도록 준비합니다.
- Optimization restrictions :
이 영역은(위 3가지) 컴파일러가 자동으로 작업하는 영역으로 개발자가 작업하진 않습니다.
1 - 1. Resolve the function & Put the arguments in the right places
Swift에선 함수 호출 시 파라미터를 CPU가 적절히 처리 할 수 있게(CPU 레지스터 주소) 배치해야 합니다.
(위 그림에서 파라미터 mov x20, x24와 mov x0, x1이 있는데요, 이는 프로세서 CPU 내부 레지스터에 해당 파라미터를 이동하는 명령입니다.)
즉, request 파라미터는 특정 레지스터에 위치해야 한다는 의미입니다.
최신 프로세서는 보통 이 비용을 레지스터 이름을 바꿔 숨길 수 있으므로 실질적으로 큰 영향을 주진 않는다고 WWDC에선 소개하고 있네요. (이 부분이 와닿지 않는다면 접은 글을 확인)
더보기레지스터 리네이밍
CPU가 파라미터를 처리할 때 비용을 최적화하는 기법
- 레지스터 리네이밍은 파이프라인에서 같은 이름의 레지스터가 여러 번 사용될 때 생기는 충돌을 방지하기 위한 기법
- 프로세서는 동일한 레지스터 이름을 실제로 논리적인 레지스터로 할당하고 내부에선 다른 물리적 레지스터로 바꿔치기함으로써 병목 현상을 피하고, 함수 호출에서 인수를 처리하는 비용을 줄일 수 있습니다.
- 실제 논리적으로 레지스터를 병렬로 처리하게 되면 같은 논리적 레지스터의 이름이더라도 실제론 서로 다른 물리적 레지스터에 맵핑되어 있어서 충돌을 피할 수 있습니다.
- 예를 들어, 프로그램 상에서 x0라는 레지스터가 여러 번 쓰일 수 있지만, 실제 CPU 내부에서는 x0라는 이름을 갖는 물리적 레지스터가 아닌 다른 레지스터가 사용될 수 있습니다.
- 즉, 인수를 올바른 레지스터에 배치하는 비용을 레지스터 이름을 바꿔치기(리네이밍)라는 기법으로 효율적으로 처리해, 성능에 큰 영향을 미치지 않도록 최적화할 수 있다는 뜻입니다.
요약하자면, 함수 호출 시 파라미터를 레지스터에 적절히 배치해야 하지만, 현대 프로세서는 레지스터 리네이밍 기법을 사용해 이로 인한 성능 저하를 최소화할 수 있다는 것입니다.
결국엔 정적 디스패치와, 동적 디스패치에 의해 비용이 결정되는 부분이 개발자에게 가장 중요한 요소로 결정하게 됩니다.
더보기[디스패치]
- 정적 디스패치
컴파일 타임에서 어떤 함수를 호출할지 알 경우 정적 디스패치에 해당합니다. 이는 Swift에서 더 효율적이고 더 빠르게 작동하게 됩니다.
[사례]
- protocol extension
- final 키워드를 사용한 class
- 동적 디스패치
런타임 상황에서 어떤 함수가 호출될지 알경우 동적 디스패치에 해당합니다.
다형성 과 같은 강력한 추상화에 사용하는 메커니즘 상속이나 오버라이드를 통해 다형성을 구현한 경우 해당되겠죠.
[사례]
- protocol에 정의한 Method
- class 메서드
1 - 2 Allocate space for the function's local state
함수 호출 비용의 마지막으로 비용은 로컬 상태 저장 부분입니다.
Swift는 C스택(Swift는 C언어와 동일한 환경에서 동작합니다.)에 함수에서 사용할 로컬 변수들을 Stack Pointer를 기준으로 메모리를 할당하고 해제합니다.
아래 그림은 왼쪽부터 순서대로 할당 전 - 할당 - 소멸 과정의 그림입니다.
스택 메모리 영역 할당과 소멸 'IOS > WWDC24' 카테고리의 다른 글
[WWDC24] Swift의 성능 살펴보기 (2 / 3) (0) 2025.02.08 [WWDC19] Building Custom Views with SwiftUI Session, SwiftUI Layout 크기 메커니즘 알아보기 (2) 2024.09.21 [WWDC24] Translation API_한번에 여러 컴포넌트 번역하기 (0) 2024.09.14 [WWDC24] Translation API_소개 (3) 2024.09.08