일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 데이터구조
- 클라우드컴퓨팅
- 사이버보안
- 자료구조
- 소프트웨어공학
- 코딩
- 버전관리
- Yes
- 자바스크립트
- 인공지능
- 파이썬
- 데이터분석
- 빅데이터
- 웹개발
- 데이터베이스
- 네트워크
- 네트워크보안
- 프로그래밍
- 머신러닝
- 보안
- 프로그래밍언어
- 데이터과학
- 소프트웨어
- 알고리즘
- 2
- 컴퓨터과학
- 컴퓨터공학
- 컴퓨터비전
- 딥러닝
- I'm Sorry
- Today
- Total
스택큐힙리스트
리눅스에서 실행되는 C++ 코드를 프로파일링하는 방법은 무엇인가요? 본문
리눅스에서 실행되는 C++ 애플리케이션에서 실행 속도가 느린 코드 영역을 어떻게 찾을 수 있나요?
답변 1
당신의 목표가 프로파일러를 사용하는 것이라면, 제안된 것 중 하나를 사용하세요.
하지만, 만약 당신이 서둘러야 하고 디버거에서 프로그램이 주관적으로 느리게 실행되고 있다면, 성능 문제를 찾는 간단한 방법이 있습니다.
여러 번 중지하고 매번 콜 스택을 확인하세요. 시간의 일부를 낭비하는 코드 (20% 또는 50% 또는 기타)가 있다면, 각 샘플에서 그것을 적발할 가능성이 있습니다. 따라서 대략적으로 보면, 그 문제가 있는 샘플의 비율과 거의 비례합니다. 학습에 필요한 이론적 추측은 필요하지 않습니다. 문제가 무엇인지 추측이 있다면, 이 기술로 증명하거나 반증할 수 있습니다.
아마도 여러 크기의 성능 문제가 있을 것입니다. 그 중 하나를 해결하면 남은 문제는 더 큰 비율을 차지하고, 다음 테스트에서 쉽게 발견할 수 있습니다. 이 확대 효과는 여러 문제에서 합쳐지면, 현저한 속도 향상을 이끌어낼 수 있습니다.
경고 : 프로그래머들은 자신들이 직접 사용해보지 않은 이상 이 기술에 대해 회의적입니다. 프로파일러는이 정보를 제공한다고 말할 수 있지만 전체 호출 스택을 샘플링하고 임의의 샘플 집합을 검사할 수있게하면 그것이 참이됩니다. (요약에서 통찰력이 상실되기 때문입니다.) 호출 그래프는 동일한 정보를 제공하지 않습니다.
그들은 지시 수준에서 요약하지 않습니다.
재귀의 존재에서 혼란스러운 요약을 제공합니다.
그들은 그것이 장난감 프로그램에서만 작동한다고 말할 것이며, 실제로는 모든 프로그램에서 작동하며 더 큰 프로그램에서는 더 잘 작동하는 것으로 보입니다. 왜냐하면 그들은 찾을 문제가 더 많기 때문입니다. 그들은 때로는 문제가 없는 것을 찾는다고 말할 수 있지만, 그것은 단지 한 번 본 것일 때만 해당됩니다. 여러 샘플에서 문제를 볼 경우에만 실제 문제입니다.
P.S. 이 경우 자바와 같이 시간 지점에서 스레드 풀의 호출 스택 샘플을 수집하는 방법이 있다면 멀티 스레드 프로그램에서도 수행할 수 있습니다.
P.P.S. 대략적으로 말하자면, 소프트웨어 내에서 추상화 계층이 많을수록 성능 문제의 원인이 될 가능성이 높습니다 (그리고 성능 향상의 기회가 될 수 있습니다).
추가된 내용: 스택 샘플링 기술은 순환(recursion)의 존재에서도 동일하게 작동한다는 것이 분명하지 않을 수 있습니다. 그 이유는 샘플에 포함된 횟수와 관계없이 해당 명령을 제거했을 때 절약되는 시간은 샘플의 일부분으로 근사화 되기 때문입니다.
자주 듣는 다른 이의 이의는 그것은 어디에서든 무작위로 멈출 것이며, 실제 문제를 놓칠 것이다 입니다. 이는 실제 문제가 무엇인지에 대한 이전 개념 때문입니다. 성능 문제의 중요한 특성 중 하나는 예상을 빗나가는 것입니다. 샘플링은 문제점이 있다는 것을 알려주며, 첫 번째 반응은 비신뢰일 수 있습니다. 이것은 자연스러운 것이지만, 문제를 찾으면 그것이 실제 문제임을 확신할 수 있으며, 그 반대도 마찬가지입니다.
추가: 어떻게 작동하는지에 대한 베이지안 설명을 해보겠습니다. 어떤 지시어 I (호출 또는 그 외)가 호출 스택에 어떤 비율의 시간 동안 있으며, 그만큼의 비용이 듭니다. 단순화를 위해, 우리는 f이 얼마나 되는지 모르지만 0.1, 0.2, 0.3, ... 0.9, 1.0 중 하나이며, 이러한 각각의 가능성의 사전 확률이 0.1이고, 따라서 이들 비용 모두가 사전에 동일하게 가능성이 높습니다.
그러면 우리는 딱 2개의 스택 샘플만 가져온다고 가정해보겠습니다. 그리고 우리는 두 샘플에서 모두 I 지시어를 발견합니다. 이를 o=2/2!@ 로 지정합니다. 이는 I 의 빈도수 f!@ 에 대한 새로운 추정치를 제공합니다.
Prior
P(f=x) x P(o=2/2|f=x) P(o=2/2&&f=x) P(o=2/2&&f >= x) P(f >= x | o=2/2)
0.1 1 1 0.1 0.1 0.25974026
0.1 0.9 0.81 0.081 0.181 0.47012987
0.1 0.8 0.64 0.064 0.245 0.636363636
0.1 0.7 0.49 0.049 0.294 0.763636364
0.1 0.6 0.36 0.036 0.33 0.857142857
0.1 0.5 0.25 0.025 0.355 0.922077922
0.1 0.4 0.16 0.016 0.371 0.963636364
0.1 0.3 0.09 0.009 0.38 0.987012987
0.1 0.2 0.04 0.004 0.384 0.997402597
0.1 0.1 0.01 0.001 0.385 1
P(o=2/2) 0.385
마지막 열에는 예를 들어, f >= 0.5일 확률이 이전 가정인 60%보다 92%로 증가되었다는 것이 나와 있습니다.
가정이 다르다고 가정해 봅시다. 우리가 거의 확실한 .991이라고 가정하고 나머지 가능성은 거의 불가능하다고 생각하는 경우 (0.001). 다시 말해, 우리의 사전 확신은 I이 싼 것이라는 것입니다. 그러면 우리는 다음과 같이 얻을 수 있습니다.
Prior
P(f=x) x P(o=2/2|f=x) P(o=2/2&& f=x) P(o=2/2&&f >= x) P(f >= x | o=2/2)
0.001 1 1 0.001 0.001 0.072727273
0.001 0.9 0.81 0.00081 0.00181 0.131636364
0.001 0.8 0.64 0.00064 0.00245 0.178181818
0.001 0.7 0.49 0.00049 0.00294 0.213818182
0.001 0.6 0.36 0.00036 0.0033 0.24
0.001 0.5 0.25 0.00025 0.00355 0.258181818
0.001 0.4 0.16 0.00016 0.00371 0.269818182
0.001 0.3 0.09 0.00009 0.0038 0.276363636
0.001 0.2 0.04 0.00004 0.00384 0.279272727
0.991 0.1 0.01 0.00991 0.01375 1
P(o=2/2) 0.01375
이제 P(f >= 0.5)는 26%로 이전 추정치인 0.6%보다 올랐다고 합니다. 그래서 베이즈는 우리가 I의 예상 비용 추정치를 업데이트 할 수 있게 해줍니다. 데이터 양이 적으면 비용이 정확하게 무엇인지는 알려주지 않지만, 수정할 가치가 있을 만큼 충분히 크다는 것을 알려줍니다.
그것을 바라보는 또 다른 방법은 Rule Of Succession 라고합니다. 동전을 2번 던졌을 때 두 번 다 머리가 나오면, 그 동전의 추정 중량에 대해 무엇을 알려줍니까? 존경받는 방법으로 대답하는 것은 평균 값이 (number of hits + 1) / (number of tries + 2) = (2+1)/(2+2) = 75% 인 베타 분포라고 말하는 것입니다.
(핵심은 우리가 I을 한 번 이상 보는 것입니다. 한 번만 본다면, 그것은 f > 0 이라는 것 외에는 우리에게 많은 정보를 제공하지 않습니다.)
따라서 매우 적은 수의 샘플도 그것이 보는 지시어 비용에 대해 많은 정보를 제공할 수 있습니다. (그리고 그 비용에 비례하여 평균적으로 자주 볼 것입니다. 샘플 n 이 산출되고, 그 비용이 f 라면,I 는 nf+/-sqrt(nf(1-f)) 샘플에서 나타납니다. 예를 들어, n=10 , f=0.3 이것이 3+/-1.4 샘플입니다.)
추가 : 측정과 무작위 스택 샘플링의 차이를 직관적으로 이해하기 위해 :
이제는 월-클락 시간에도 스택을 샘플링하는 프로파일러가 있지만, 그 결과는 측정치(또는 핫 패스 또는 핫 스팟)이며, 거기에서 병목 현상이 쉽게 숨어있을 수 있습니다. 그러나 그들이 보여주지 않는 것(그리고 그들이 쉽게 할 수 있는 것)은 실제 샘플 자체입니다. 그리고 당신의 목표가 병목을 찾는 것이라면, 볼 필요가 있는 샘플 수는 평균적으로 시간 분수로 나눈 2입니다.
따라서 시간이 30% 걸린다면, 2 / 0.3 = 평균 6.7 샘플이 그것을 보여줄 것이고, 20개의 샘플이 그것을 보여줄 확률은 99.2%입니다.
여기는 측정치와 샘플 스택을 조사하는 차이를 뜻하는 즉흥적인 예시입니다.
병목현상은 이러한 하나의 대형 덩어리이거나 많은 작은 덩어리 중 하나일 수 있으며, 이는 상관없습니다.
측정은 수평적입니다. 이는 특정 루틴이 얼마나 시간을 소요하는지의 분수를 나타냅니다. 샘플링은 수직적입니다. 그 순간 프로그램 전체가 하고 있는 일을 피할 방법이 있다면, 그리고 두 번째 샘플에서 그것을 본다면 병목 현상을 찾았습니다. 이것이 차이를 만들어 내는 것입니다. 오직 얼마나 많은 시간이 소요되는 것이 아니라, 그 시간이 어디에 쓰이는지를 전적으로 알아보는 것입니다.
답변 2
C++ 코드를 Linux에서 프로파일링하는 방법C++ 개발자들은 대개 코드의 병목 현상을 파악해 시스템의 성능을 최적화하는 일에 많은 시간을 할애합니다. 이를 위해서는 C++ 코드를 프로파일링하는 것이 중요한데, 이 글에서는 Linux에서 C++ 코드를 프로파일링하는 방법에 대해 알아볼 것입니다.
1. Perf 도구 사용하기
Perf는 Linux 커널에 내장된 프로파일링 도구입니다. Perf는 프로세스의 주요 작업(예: 함수 호출)을 추적하고, CPU 사용량, 메모리 사용량 등 다양한 프로파일링 정보를 수집합니다. Perf를 사용하려면 다음과 같은 명령어를 입력합니다.
```
perf record
perf report
```
2. Gprof 도구 사용하기
Gprof는 프로파일링 데이터를 분석하여 함수 호출 그래프와 함수 당 실행시간 등의 자세한 정보를 제공하는 GNU 프로파일링 도구입니다. Gprof를 사용하려면 프로그램을 -pg 옵션과 함께 컴파일해야 합니다.
```
g++ -pg -o
```
3. Valgrind 도구 사용하기
Valgrind는 C++ 코드의 메모리 누수와 사용하지 않는 메모리를 감지하는 프로파일링 도구입니다. Valgrind를 사용하려면 다음과 같은 명령어를 입력합니다.
```
valgrind --tool=memcheck
```
위와 같은 도구를 사용하면 C++ 코드를 효율적으로 프로파일링할 수 있습니다. 이를 통해 병목 현상을 찾아 최적화를 수행하고, 높은 수준의 실행 시간 성능을 달성할 수 있습니다.