본문 바로가기
-----ETC-----/C++ 마스터 시리즈

[C++ 마스터] Day 28: 최적화 기법과 코드 프로파일링

by cogito21_cpp 2024. 8. 1.
반응형

최적화 기법

프로그램의 성능을 향상시키기 위해 여러 가지 최적화 기법을 사용할 수 있습니다. 여기서는 주요 최적화 기법들을 살펴보겠습니다.

 

1. 컴파일러 최적화

컴파일러는 다양한 최적화 옵션을 제공하여 코드 실행 성능을 향상시킬 수 있습니다. 예를 들어, -O2 또는 -O3 옵션을 사용하여 최적화를 수행할 수 있습니다.

g++ -O2 program.cpp -o program
g++ -O3 program.cpp -o program

 

2. 인라인 함수 (Inline Functions)

인라인 함수는 함수 호출 오버헤드를 줄여줍니다. inline 키워드를 사용하여 함수를 인라인으로 정의할 수 있습니다.

#include <iostream>

inline int add(int a, int b) {
    return a + b;
}

int main() {
    std::cout << add(3, 4) << std::endl;
    return 0;
}

 

3. 반복문 최적화

반복문에서 불필요한 연산을 줄이는 것이 중요합니다. 예를 들어, 반복문에서 상수 계산을 반복하지 않도록 할 수 있습니다.

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec(1000, 1);
    int sum = 0;

    for (size_t i = 0; i < vec.size(); ++i) {
        sum += vec[i];
    }

    std::cout << "Sum: " << sum << std::endl;
    return 0;
}

 

4. 데이터 구조 최적화

적절한 데이터 구조를 선택하여 성능을 향상시킬 수 있습니다. 예를 들어, 검색이 빈번한 경우 해시 테이블을 사용하면 성능이 향상될 수 있습니다.

#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap;
    umap[1] = "one";
    umap[2] = "two";
    umap[3] = "three";

    std::cout << umap[2] << std::endl;
    return 0;
}

 

코드 프로파일링

코드 프로파일링은 프로그램의 성능 병목 지점을 찾아내는 데 사용됩니다. 주요 도구로는 gprof, valgrind, perf 등이 있습니다.

 

1. gprof 사용법

gprof는 GNU 프로파일러로, 프로그램의 성능을 분석할 수 있습니다.

g++ -pg program.cpp -o program
./program
gprof program gmon.out > analysis.txt

 

2. valgrind 사용법

valgrind는 메모리 사용을 분석하고, 메모리 누수와 같은 문제를 찾아내는 데 사용됩니다.

valgrind --tool=memcheck ./program

 

3. perf 사용법

perf는 Linux에서 사용할 수 있는 성능 분석 도구로, 다양한 성능 데이터를 수집할 수 있습니다.

perf record ./program
perf report

 

예제 문제

문제 1: 컴파일러 최적화 옵션을 사용하여 프로그램의 실행 속도 비교

컴파일러 최적화 옵션 -O0, -O2, -O3를 사용하여 프로그램을 컴파일하고, 각 최적화 옵션에 따른 실행 속도를 비교하는 프로그램을 작성하세요.

 

해설:

  1. 프로그램 작성 (program.cpp):
#include <iostream>
#include <chrono>

using namespace std;
using namespace chrono;

int main() {
    auto start = high_resolution_clock::now();

    long long sum = 0;
    for (long long i = 0; i < 1000000000; ++i) {
        sum += i;
    }

    auto end = high_resolution_clock::now();
    duration<double> elapsed = end - start;

    cout << "Sum: " << sum << endl;
    cout << "Elapsed time: " << elapsed.count() << " seconds" << endl;

    return 0;
}
  1. 컴파일 및 실행:
g++ -O0 program.cpp -o program_O0
g++ -O2 program.cpp -o program_O2
g++ -O3 program.cpp -o program_O3

./program_O0
./program_O2
./program_O3

 

이 프로그램은 컴파일러 최적화 옵션에 따른 실행 속도를 비교합니다.

 

문제 2: gprof를 사용하여 함수별 실행 시간을 분석

gprof를 사용하여 프로그램의 함수별 실행 시간을 분석하는 프로그램을 작성하세요.

 

해설:

  1. 프로그램 작성 (program.cpp):
#include <iostream>

using namespace std;

void function1() {
    for (volatile int i = 0; i < 1000000; ++i);
}

void function2() {
    for (volatile int i = 0; i < 1000000; ++i);
}

int main() {
    function1();
    function2();
    return 0;
}
  1. 컴파일 및 실행:
g++ -pg program.cpp -o program
./program
gprof program gmon.out > analysis.txt

 

이 프로그램은 gprof를 사용하여 함수별 실행 시간을 분석합니다.

 

문제 3: valgrind를 사용하여 메모리 누수 검출

valgrind를 사용하여 메모리 누수를 검출하는 프로그램을 작성하세요.

 

해설:

  1. 프로그램 작성 (program.cpp):
#include <iostream>

using namespace std;

void memoryLeak() {
    int* arr = new int[100];
}

int main() {
    memoryLeak();
    return 0;
}
  1. 컴파일 및 실행:
g++ program.cpp -o program
valgrind --tool=memcheck ./program

 

이 프로그램은 valgrind를 사용하여 메모리 누수를 검출합니다.

 

다음 단계

28일차의 목표는 C++의 최적화 기법과 코드 프로파일링에 대해 학습하는 것이었습니다. 다음 날부터는 C++에서의 디자인 패턴에 대해 다룰 것입니다.

 

내일은 "C++에서의 디자인 패턴"에 대해 다룰 예정입니다. 질문이나 피드백이 있으면 댓글로 남겨 주세요!

반응형