일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 스마트포인터
- moreeffectiveC++
- 약참조
- BFS
- 언리얼가비지컬렉터
- 프로그래머스
- UML관련
- 정렬알고리즘
- 람다
- 언리얼엔진구조체
- 애셋로드
- 강참조
- UE4 커스텀로그
- 람다사용정렬
- 선택정렬
- unorder_map
- 델리게이트
- stl
- 크리티컬섹션
- 데이터애셋
- dataasset
- 알고리즘
- UE_LOG
- 정렬
- C++
- map
- C++최적화
- 자료구조
- enumasByue
- UELOG
- Today
- Total
기억을 위한 기록들
[CPP] C++ 최적화에 관하여 (1-3) 본문
1. 최적화란
- 더 좋은 컴파일러 사용, 최적화 설정 사용
당연히 돼있을 수도 있지만 안 돼있을 수도 있다.
- 최적의 알고리즘 사용
사소한것부터 큰 것까지 최적의 알고리즘은 다양하다. 이 내용을 알기엔 모든 나의 커리어를 쏟을 만큼 쉽지 않다.
- 더 좋은 라이브러리 사용하기
표준 C++ 템플릿 및 런타임 라이브러리는 유지보수 가능해야 하고, 범용적이고 견고해야 한다.
보통 속도를 신경을 쓰지 않기 때문에 잘 확인해 보며 써야 한다.
- 메모리 할당 줄이기
메모리 관리자를 호출하는 횟수를 줄이는 방법 하나만 알고 있더라도 성공적으로 최적화를 할 수 있다고 말할 수 있다.
- 복사 줄이기
많은 복사가 메모리 할당과 관련해 발생하기 때문에 하나를 고치면 종종 나머지 하나의 문제도 사라진다.
- 계산 제거
할당과 함수 호출을 제외하면 단일 C++문의 비용은 일반적으로 중요하지 않다. 그러나 루프 내의 또는 프로그램이 이벤트를 처리할 때 같은 코드를 수백만 번 실행하면 문제가 된다.
- 최적의 자료구조를 사용
단순 자료구조를 선택하는 것만으로도 성능에 큰 영향을 미친다.
- 동시성을 증가시키기
천천히 하는 것보다 여러 가지 일을 프로세서에 나눠 분배하면 더 빨라지겠지?
- 메모리 관리 최적화
동적 메모리 할당을 하며 필요한 기법들이 있다.
2. 컴퓨터 하드웨어와 최적화
- 메모리 접근 비용은 프로세서의 다른 비용을 압도한다.
- 정렬되지 않은 메모리에 접근하는 시간은 모든 바이트가 동일한 워드에 있을 때보다 2배 오래 걸립니다.
C++ 컴파일러는 구조체 내 각 필드의 시작 주소가 필드 크기의 배수인 바이트 주소가 되도록 정렬한다. 그러나 이는 사용되지 않는 데이터가 구조체에 포함되어 구멍이 되는 문제를 초래. 구조체에서 데이터 필드의 크기와 순서에 주의를 기울이자.
- 많이 사용하는 메모리는 적게 사용하는 메모리 위치보다 빨리 접근할 수 있습니다.
그게 캐시 메모리(Cache Memory)
- 인접한 위치에 있는 메모리는 인접하지 않은 위치에 있는 메모리보다 더 빨리 접근할 수 있습니다.
-캐싱 때문에 전체 프로그램의 콘텍스트에서 실행되는 함수는 테스트 하네스(테스트용 소프웨어와 데이터의 집합)에서 실행되는 동일한 함수보다 느리게 실행될 수 있습니다.
-실행 스레드 간 공유하는 데이터에 접근하는 속도는 공유하지 않는 데이터에 접근하는 것보다 훨씬 느립니다.
- 계산은 의사 결정보다 빠르다.
- 모든 프로그램은 다른 프로그램들과 컴퓨터 자원을 놓고 경쟁한다.
- 프로그램이 시동 시간이나 최고 부하 시간에 실행되어야 한다면, 해당 프로그램의 성능은 해당 부하 상태에서 측정해야 한다.
- 모든 대입문, 함수 인수 초기화, 함수 반환 문은 생성자를 호출하며, 그 생성자가 얼마나 많은 코드를 가지고 있는지 알 수 없습니다.
- 일부 문장은 많은 양의 계산을 숨깁니다. 문장의 형태로는 비용이 얼마나 드는지 알 수 없다.
- 동기화 코드는 실행에 가능한 스레드가 데이터를 공유할 때 얻을 수 있는 동시성을 줄입니다.
3. 성능 측정
- 성능은 반드시 측정해야 한다.
- 테스트 가능한 예측을 만들고 적어두자.
- 코드 변경 사항을 기록해두자
- 각 테스트를 문서화했다면, 빠르게 반복 수행할 수 있다.
- 프로그램의 코드가 10%가 실행시간의 90%를 소비한다.
- 정확한 측정을 위해서는 정밀하고 동시에 충실해야 한다.
- 해상도(resolution)는 정확하지 않다.
- 개발자가 큰 성능 변화를 가져오는 부분만 받아들인다면, 방법론에 크게 신경 쓸 필요가 없어진다.
- C++ 문장의 비용이 얼마나 높은지 추정하려면, 문장이 메모리를 몇 번 읽고 썼는지 세면 된다.
4. 문자열 최적화
- 문자열은 동적으로 할당되기 때문에 사용하는데 비용이 많이 든다. 또한 표현식에서 값처럼 작동하며 구현 코드에서 복사를 많이 한다.
- 문자열을 값이 아닌 객체로 처리하면 할당 및 복사 횟수를 줄일 수 있습니다.
값처럼 작동하지만 복사하는 비용이 큰 것을 설명하는 프로그래밍 용어 : 카피 온 라이트(Copy On Write)(COW)
- 문자열 공간을 예약하면 오버헤드를 줄일 수 있습니다.
string사용 시 reserve 함수를 사용하는 게 좋다.
- 문자열을 가리키는 const 참조를 함수에 전달하는 방법은 값을 전달하는 방법과 비슷해 보이지만 더 효율적입니다.
void DoSomething(std::string const& s);
- 함수의 출력용 매개변수를 참조로 전달하면 인수의 저장 공간을 재사용하므로 새로운 저장 공간을 할당하는 방법보다 훨씬 효율적입니다.
void DoSomething(std::string& output); //string을 생성해서 return 하는것보단,output변수로 참조전달을 해준다.
- 할당 오버헤드를 제거하는 작업도 최적화라고 할 수 있습니다.
- 다른 알고리즘을 사용하는 것은 최적화하기 쉽고 더 효율적인 방법입니다.
- 표준 라이브러리 클래스는 범용적으로 간단하게 구현해야 합니다. 반드시 성능이 뛰어나야 한다거나 특정용도에 최적되어야 할 필요는 없습니다.
5. 알고리즘 최적화
- 상수 시간을 갖는 알고리즘을 홍보한다면 의심해야 봐야 한다. 시간 비용이 O(n)일 수도 있다.
- 효율적인 알고리즘을 여러 개 결합해서 사용하면 전체 실행시간이 O(n^2) 이상이 될 수도 있다.
- 이진 검색은 시간비용이 O(logn)이라 성능은 뛰어나지만 가장 빠른 검색 알고리즘은 아니다. 보간 검색의 시간비용은 O(loglogn)이고 해싱의 시간 비용은 상수 시간이다.
- 항목이 4개 미만인 작은 테이블에서는 모든 검색 알고리즘이 검사하는 항목의 수가 거의 같다.
6. 동적 할당 변수 최적화
- 성능 관점에 보면 new는 우리의 친구가 아니다.
- 메모리 관리자의 호출 횟수를 줄이는 방법을 알고 있다면 효과적으로 최적화할 수 있다.
- 프로그램은 ::operator new()와 ::operator delete()의 정의를 제공해 전역 범위에서의 메모리 할당 방법을 변경할 수 있다.
- 프로그램은 malloc()과 free()를 대체해 전역 범위에서의 메모리 관리 방법을 변경할 수 있다.
- 스마트 포인터는 동적 변수의 소유권을 자동화한다.
- 동적 변수의 소유권을 공유하면 비용이 더 크다.
공유 포인터
- 클래스 인스턴스를 정적으로 만드세요.
MyClass* myInstance = new MyClass("Hello",123);
대신하여 정적으로 생성하는 방법
MyClass myInstance("Hello",123);
- 클래스 멤버 변수를 정적으로 만들고 필요하다면 2단계 초기화를 사용하세요.
https://stackoverflow.com/questions/12653724/use-cases-for-two-phase-initialization
- 동적 변수를 소유하기 위한 소유 포인터를 사용하세요. 그리고 소유권을 공유하는 대신 소유하지 않는 포인터를 사용하세요.
- 출력용 매개변수에 데이터를 전달하는 복사 없는 함수를 만드세요
이전과 마찬가지로 함수 안에서 생성하여 return 하지 말고 output용 매개변수를 넣자.
- 이동 문법을 구현하세요
C++11에 추가된 이동 문법. (&&연산자)
http://sangsangworld.blogspot.com/2015/06/c11_37.html
- 평평한 자료구조를 더 많이 사용하세요.
일반 배열이나 vector는 나란히 있는 평평한 자료구조, 그 외 list/map 등은 노드 기반이라 평평하지 않음.
'C & CPP' 카테고리의 다른 글
[CPP] C++ 최적화에 관하여 (3-3) (0) | 2021.08.22 |
---|---|
[CPP] C++ 최적화에 관하여 (2-3) (0) | 2021.08.16 |
[C&CPP] assert/static_assert 관련 (0) | 2021.04.15 |
[CPP]반환 값 최적화(return value optimization)RVO란?/NRVO (3) | 2021.04.14 |
[C++] 정수 자료형의 범위/int8, int16, int32, int64.. (0) | 2021.04.02 |