2013-05-02 1 views
-1

프로세서 시간을 이해하는 데 어려움이 있습니다. 이 프로그램의 결과 :이 프로그램을 실행할 때마다 CPU 시간이 다른 이유는 무엇입니까?

#include <iostream> 
#include <chrono> 

// the function f() does some time-consuming work 
void f() 
{ 
    volatile long double d; 
    int size = 10000; 
    for(int n=0; n<size; ++n) 
     for(int m=0; m<size; ++m) 
      d = n*m; 
} 

int main() 
{ 
    std::clock_t start = std::clock(); 
    f(); 
    std::clock_t end = std::clock(); 

    std::cout << "CPU time used: " 
       << (end - start) 
       << "\n"; 
} 

보인다 임의로 I, 왜 이러한 이산 값 놀랐다 우선 000 000 220 000210 (230) 사이에 변동한다. 그런 다음 std::clock()approximate processor time 만 반환한다는 것을 알았습니다. 따라서 std::clock()에 의해 반환되는 값은 10 000의 배수로 반올림됩니다. 이는 CPU 시간의 최대 차이가 20 000 (10 000 == 첫 번째 호출에서 반올림 오류 std::clock() 및 10 000이 두 번째).

f()의 몸체에 int size = 40000;으로 변경하면 반올림으로 설명 할 수없는 3 400 000 ~ 3 500 000 범위의 변동이 발생합니다.

내가 위키 백과에서 clock rate에 대해 읽은 것을에서

:

CPU는 클럭 고정 된 수의 각 명령을 실행 에 틱 (또는 클럭 사이클)가 필요합니다. 시계가 빠를수록 더 많은 명령이 CPU가 초당 실행할 수 있습니다.

프로그램 (나는 나의 희망하는) 결정 인 경우입니다

, 완료하는 데 필요한 CPU 시간이 있어야한다 : 항상

  1. 지침의 수보다 같은
  2. 약간 높은 수행

내 프로그램은 적어도 3 * size * size 명령어를 수행해야하므로 실험 결과가 표시되지 않습니다. 내가 잘못하고있는 것을 설명해 주시겠습니까?

+2

프로그램의 결과는 결정적 일 수 있지만, 실행 시간은 그렇지 않습니다. 왜냐하면 당신은 아마 당신의 상자에서 다른 것을 실행하고 있기 때문입니다. –

+0

코드가 다른 단어와 완전히 분리되어 실행되지 않습니다. 이론 상으로는이 사소한 프로그램의 절반은 몇 세기 동안 실행이 느슨하게 중단 될 수 있습니다. – thecoshman

+0

당신은 (a) 컴퓨터와 (b) 시간 공유 운영 체제가 어떻게 작동하는지 단순하게 예상 할 수 있습니다. –

답변

2

바이너리를 실행중인 하드웨어를 지정하지 않았습니다.

인터럽트 기반 CPU가 있습니까?

멀티 태스킹 운영 체제입니까?

처음부터 끝까지 특정 코드를 실행하는 데 걸린 시간과 CPU가 부족한 다른 모든 것들을 처리하는 데 CPU의 사이클 시간 (위키 백과에서 말하는 CPU 클럭)을 잘못 생각하는 것입니다 동시에.

또한 레벨 1 캐시의 모든 실행 코드이거나 레벨 2 또는 주 메모리 또는 디스크의 일부입니다 ... 다음 번에 실행하면 어떨까요?

+1

이론적으로'clock()'은 프로세스에 할당 된 CPU 시간을 측정하므로 캐시 만 문제가되어야합니다. (실제로는'clock()'은 마이크로 소프트 라이브러리에서 깨져서 전혀 쓸모가 없다.) –

6

먼저 위키 백과에서 인용 한 진술은 단순히 거짓입니다. 20 년 전 사실일지도 모르지만 (항상 그런 것은 아니지만 심지어 ) 심지어 오늘은 완전히 거짓입니다. 당신의 타이밍에 영향을 미칠 수있는 많은 것들이 있습니다

  • 첫 번째 : Windows에서 실행하는 경우, clock는, 완전히 신뢰할 수없는 고장이다. CPU 시간이 아닌 경과 시간의 차이 ( )를 반환합니다. 그리고 경과 시간은 프로세서가 수행하고있는 다른 모든 종류의 에 달려 있습니다.

  • 그 외에도 캐시 미스와 같은 것들은 매우 중요한 영향을 미칩니다. 그리고 특정 데이터 조각이 에 있는지 여부는 프로그램이 인지 여부에 따라 달라질 수 있습니다.

일반적으로 10 % 미만의 값은 캐싱 문제로 인해 쉽게 발생할 수 있습니다. 그리고 실행중인 빌드가 있었는지 아니면 이 아닌지에 따라 Windows에서 10의 차이점 (차이점은 )을 확인했습니다.

+0

+1 ... 또한 다중 처리 운영체제에서는'f()'이전 줄'std :: clock_t start = std :: clock();'바로 다음에. – deepmax

+0

@MM. 어떤 중간 시간이라도 프로세스에 귀속되는 CPU 시간이 아니기 때문에 그럴 필요는 없습니다. (그러나 'clock()'의 구현이 망가질 경우 중요 할 것입니다.) –

+0

이 답변을 주셔서 감사합니다. 실제로 시계가 실제로 깨 졌다고 시간을 측정하는 좋은 방법이 있습니까? –

1

주어진 시간대의 CPU 시간은 실제로 "고정"입니다. 그러나 최신 컴퓨터에서는 시스템에서 다른 일이 일어나 코드 실행을 방해합니다. 새 전자 메일이 있는지 또는 HP 프린터 소프트웨어가 업데이트를 확인했는지 또는 바이러스 백신 소프트웨어가 약간의 확인을 위해 실행을 결정할 때 전자 메일 소프트웨어가 깨어나서 캐시가 지워지는 경우 일 수 있습니다 당신의 기억에는 바이러스, 기타 등등, 등등이 포함되어 있습니다.

이것은 또한 시스템의 CPU 시간 계산이 100 % 정확하지 않은 문제로 인해 발생합니다 - "시계 틱"및 유사 따라서 예를 들어 인터럽트가 들어오는 네트워크 패킷을 처리하는 데 사용되는 시간 또는 하드 디스크가 인터럽트를 처리하는 시간, 또는 이러한 모든 계정이 "현재 실행중인 프로세스"로 "다른 밀리 초"로 표시되는 타이머 인터럽트가 있습니다. Windows라고 가정하면 더 많은 "기능"이 있습니다. 이는 역사적인 이유와 다른 이유로 인해 std::clock()은 단순히 시간을 반환하기 만하면 실제로 프로세스에서 사용한 시간이 아닙니다. exampple에 대한 그래서 : 그것은 x의 입력 값을 10 초 걸렸다 경우

t = clock(); 
cin >> x; 
t = clock() - t; 

그 십초의 비록 9.999은 프로그램을, 유휴 과정에서 소비되지 않은 10 초 시간 t을 떠날 것이다.

+0

C 표준을 인용하자면 : "clock 함수는 프로그램 [...]"(강조가 추가됨)에 사용 된 _processor_ 시간에 대한 구현의 최상의 근사값을 반환합니다. Windows 구현을 올바르게 설명하는 유일한 단어는 "고장"입니다. –

+1

그렇습니다. 아마도 DOS와 어쩌면 초기 Windows에서는'clock()'을 사용하여 다른 시간 관리 작업을하기 때문에 코드가 깨져서 이후 버전으로 이식 될 때 "우리는 할 수 있습니다. 코드가 깨지는 것을 허용하지 않습니다 ... " –

1

프로그램이 결정적이지 않은 라이브러리 및 시스템 기능을 사용하기 때문에 프로그램이 결정적이지 않습니다.

특정 예를 들어, 메모리를 할당 할 때 이것은 가상 메모리이며 실제 메모리에 매핑되어야합니다. 커널 코드를 실행하는 시스템 호출이지만 스레드에서 발생하며 시계 시간에 반영됩니다. 이 작업을 수행하는 데 걸리는 시간은 전반적인 메모리 할당 상황에 따라 달라집니다.

관련 문제