5.1 Capabilities and Limitations of Optimizing Compilers(컴파일러 최적화의 능력과 한계)
- GCC 컴파일러 등 대부분의 컴파일러는 프로그래머의 코드를 자동으로 최적화 해준다
- 본 장에서는 GCC 컴파일러 옵션을 -01로 한다. (더 범용성이 넓은 최적화 옵션) (-02가 가장 일반적인 최적화 옵션이고 -03 옵션의 경우 가장 높은 레벨 최적화가 이루어진다. 그러나 너무나 많은 소스의 변경이 이루어지기 때문에 왜곡될 위험이 있다) (-05 옵션의 경우 사이즈 최적화도 이루어지기 때문에 공간이 협소한 곳(임베디드 시스템)에서 이루어 진다)
- 컴파일러는 프로그램에 안전한 최적화를 제공해야 한다. (지나친 최적화로 인한 왜곡 발생 주의해야 함)
- 컴파일러가 안전한 최적화를 제공하도록, 프로그래머도 코드를 작성할 때, 컴파일러가 효율적인 머신 코드로 변환할 수 있도록 코드를 작성하는 노력이 필요함.
void twiddle1(long *xp, long *yp)
{
*xp += *yp;
*xp += *yp;
}
void twiddle2(long *xp, long *yp)
{
*xp += 2* *yp;
}
- 위 두 함수는 동일한 작동을 하는 것처럼 보인다.
- 그러나 twiddle2 함수가 더 효율적으로 작동한다.
- twiddle1 함수는 (two reads of *xp, two reads of *yp, and two writes of *xp) 총 6번의 메모리 참조가 발생하고 twiddle2 함수는 (read *xp, read *yp, write *xp) 총 3번의 메모리 참조만 발생한다.
- 컴파일러가 이 정도는 twiddle1을 twiddle2 방식으로 최적화 할 수 있다라고 생각하겠지요? (두 개의 포인터가 가르키는 메모리 위치가 다를 경우가 보장되면 가능하다)
- 그러나 아래 예시와 같이 , 인자인 두 개의 포인터가 가르키는 메모리 위치가 같은 경우 컴파일러는 자동으로 최적화 할 수 없다.
*xp += *xp; /* Double value at xp */
*xp += *xp; /* Double value at xp */
- twiddle1: xp에서의 값은 4배 증가한다.
*xp += 2* *xp; /* Triple value at xp */
- twiddle2: xp에서의 값은 3배 증가한다.
- 위 예시와 같이 인자가 같은 메모리 위치를 갖는 경우 다른 결과값을 내기 때문에, 컴파일러 입장에서는 twiddle1의 인자가 같은 메모리 위치를 가질 지, 아닐 지 모르기 때문에 twiddle1을 twiddle2로 최적화 할 수 없다.
- 메모리 위치가 같을 때 컴파일러가 최적화 할 수 없는 경우를 메모리 연결 (Memory aliasing)이라 한다.
- 아래 예시도 p와 q의 메모리 위치가 같을 경우와 다를 경우 다른 결과를 내기 때문에, 컴파일러가 최적화 할 수 없는 메모리 연결 (Memory aliasing)의 예시가 된다.
x = 1000; y = 3000;
*q = y; /* 3000 */
*p = x; /* 1000 */
t1 = *q; /* 1000 or 3000 */
- 위와 같이 컴파일러가 최적화 할 수 없는 경우를 최적화 장애물(Optimization blockers)이라 하는데, 또 다른 경우는 함수 호출에서 발생한다.
long f();
long func1() {
return f() + f() + f() + f();
}
long func2() {
return 4*f();
}
- func1() 함수가 f() 함수 호출 4번이 일어나고 func2() 함수가 f() 함수 호출 1번이 일어날 지라도, 동일한 결과 값을 반환할 것이라고 예측된다. 그래서 컴파일러가 func1()을 func2()로 최적화할 수 있겠다고 생각할 수 있지만,
long counter = 0;
long f() {
return counter++;
}
- f() 함수가 위와 같을 경우, 호출되는 횟수에 따라 프로그램의 동작이 변하게 된다. 이를 부가효과(Side effect)라 한다.
- func1()의 경우 0 + 1 + 2 + 3의 값을 반환하고 func2()의 경우 4 * 0의 값을 반환한다.
- 대부분의 컴파일러는 함수가 부가효과(Side efftect)를 가질 지 안가질 지 모르기 때문에, func1()을 func2()로 최적화 할 수 없다.
- 따라서 gcc를 사용하는 사용자들은 컴파일러가 효율적으로 코드를 최적화할 수 있는 방향으로 코드를 작성해야 한다.
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[CSAPP] 5.3 Program Example(프로그램 예제) (0) | 2023.01.30 |
---|---|
[CSAPP] 5.2 Expressing Program Performance(프로그램 성능의 표현) (0) | 2023.01.29 |
[CSAPP] Chapter 05. Optimizing Program Performance(프로그램 성능 최적화 하기) (0) | 2023.01.29 |
[CSAPP] 3.11 Floating-Point Code(부동소수점 코드) (0) | 2023.01.24 |
[CSAPP] 3.10 Combining Control and Data in Machine-Level Programs(기계 수준 프로그램에서 제어와 데이터 결합) (0) | 2023.01.24 |