문제

나는 포팅하는 게임이 되었 Win32API,리눅스(잘 포팅,OS X 포트의 Win32 포트 Linux).

를 구현하고 있습니다 QueryPerformanceCounter 제공하여 uSeconds 부터 프로세스를 시작:

BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
{
    gettimeofday(&currentTimeVal, NULL);
    performanceCount->QuadPart = (currentTimeVal.tv_sec - startTimeVal.tv_sec);
    performanceCount->QuadPart *= (1000 * 1000);
    performanceCount->QuadPart += (currentTimeVal.tv_usec - startTimeVal.tv_usec);

    return true;
}

이와 함께 QueryPerformanceFrequency() 을 주는 일정한 1000000 으로 주파수,잘 작동 에서 내 컴퓨터, 주고,나는 64 비트를 포함하는 변수 uSeconds 이 프로그램을 시작합니다.

그래서 이 휴대용? 나는 원하지 않는다 그것을 발견하는 다르게 작동하면 커널이 컴파일된 특정 방법에 있는 것 같습니다.나는 괜찮아요 그것이 아닌 휴대용하는 다른 무언가를 리눅스보다,그러나입니다.

도움이 되었습니까?

해결책

아마.그러나 당신이 더 큰 문제입니다. gettimeofday() 에서 발생할 수 있습 잘못된 타이밍이 있는 경우 프로세스에 시스템을 변경하는 타이머(ie,ntpd).에서"정상"리눅스,하지만,나는 믿고해상도의 gettimeofday() 은 10us.그것은 앞뒤로 이동할 수 있습과 시간,그 결과에 기초하여,프로세스에서 실행되는 시스템입니다.이를 효과적으로 만드는 당신의 질문에 대답은 아니다.

로 봐야 한다 clock_gettime(CLOCK_MONOTONIC) 타이밍을 위한 간격으로.그것은 겪고 있에서 여러 문제로 인해 멀티 코어 시스템 및 외부 시계를 설정합니다.

또한,으로 보고 clock_getres() 기능입니다.

다른 팁

높은 해상도 낮은 타이밍 오버헤드 위한 인텔 프로세서

는 경우에는 인텔 하드웨어,여기에는 방법을 읽 CPU 실시간 명령 카운터입니다.그것은 당신을 말할 것이다 CPU 사이클 실행기 때문 프로세서 부팅되었습니다.이것은 아마도 최고의 세분화된 카운터를 얻을 수 있습에 대한 성과를 측정합니다.

이는 CPU 사이클의 수.리눅스에서 당신을 얻을 수 있습니 CPU 속도에서는/proc/cpuinfo 와 나누기를 얻을 수 있습니다.변환하는이 두 배는 매우 편리합니다.

을 실행할 때 이에 상자,나

11867927879484732
11867927879692217
it took this long to call printf: 207485

인텔은 개발자 가이드 제공하는 톤의 세부 사항입니다.

#include <stdio.h>
#include <stdint.h>

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}

@버나드:

나는 것을 인정해야의 대부분의 예로 바로 갔고 있습니다.그것은 컴파일하고 작동하는 것 같다,하지만.이 안전을 위한 SMP 시스템 또는 스피드스텝?

좋은 질문이...내가 생각하는 코드를 확인 합니다.실용적인 관점에서,우리가 사용하는 회사에서도 매일 과 우리에서 실행 예쁜의 다양한 상자에서 모든 것을 2-8 코어 있습니다.물론,만,느린 ftp 를 방 등,하지만 그것은 신뢰할 수 있는 낮은 오버헤드 (지 않기 때문에 상황으로 전환 시스템-space)방법 의 타이밍.

일반적으로 어떻게 작동:

  • 를 선언한 블록의 코드를 어셈블러(휘발성도 최적화 프로그램을 떠나 혼자).
  • 실행 CPUID 명령입니다.외부 CPU 정보 (우리는 아무것도하지 않으로)그것은 동기화 CPU 의 실행 버퍼 도록 타이밍에 의해 영향을 받지 않습의 순서로 실행합니다.
  • 실행 rdtsc(읽기 타임스탬프)에 실행합니다.이를 가져옵의 수 기계 사이클 실행기 때문 프로세서 리셋되었습니다.이 64 비트 값이므로,현재 CPU 속도 그것이 감싸는 모든 194 년 정도.흥미롭게도,원래 Pentium 참조,그들이 그것을 참고 주위를 감싸는 모든 5800 년 정도.
  • 마지막 부부의 라인 상점의 값을 레지스터로 변수 lo,하 고 있는 64 비트는 반환 값.

특정 노트:

  • out-of-order execution 잘못된 결과가 발생할 수 있습니다,그래서 우리는 실행 "cpuid"명령하는 외에 몇 가지 정보 에 대해 cpu 또한 동기화하는 어떤 순서 명령어 실행이 가능합니다.

  • 가장 OS 의 동기화 카운터에서는 Cpu 시작할 때,그래서 대답은 좋은 내 나노 초입니다.

  • 최대 절전 모드 코멘트는 아마도 사실이지만,실제로 당신 아마에 대해 걱정하지 않는 타이밍에 걸쳐 최대 절전 모드의 경계.

  • 에 관한 스피드 스텝:최신 Intel Cpu 를 사용에 대한 보상하는 속도 변화를 반환합니다 조정된 횟수입니다.나는 빠른 검사 이상 일부 상자에서 우리의 네트워크와 하나를 발견 상자 이 있지 않았다:펜티엄 3 실행하는 오래된 데이터베이스 서버입니다.(이러한 리눅스 상자를,그래서 확인:grep constant_tsc/proc/cpuinfo)

  • 는 AMD Cpu,우리 주로는 인텔은 상점, 알고 있지만 우리의 일부 낮은 수준의 시스템 전문가 했 AMD 평가입니다.

희망이 만족하는 호기심,그것은 재미있고(IMHO) 에서 공부한 지역의 프로그래밍입니다.당신이 알고 때 제프와 조엘 했 에 대해 얘기하는지 여부를 알아야 프로그래머 C?나 소리는,그들에게"야 잊는 높은 수준의 C 다.어셈블러 은 당신이 무엇을 배워야 하는 경우에 당신은 무엇을 알고 싶어 컴퓨터는 다."

당신은에 관심이있을 수 있습니다 리눅스에 대한 FAQ clock_gettime(CLOCK_REALTIME)

와인이 실제로 사용하 gettimeofday()구현 QueryPerformanceCounter()그리고 알려진 많은 윈도우 게임 작업에서 리눅스와 맥.

http://source.winehq.org/source/dlls/kernel32/cpu.c#L312

http://source.winehq.org/source/dlls/ntdll/time.c#L448

그래서 그것은 말 마이크로초 단위로 명시적으로만 말해상도의 시스템 시계가 지정되지 않습니다.내 생각해상도 이 상황에서 의미하는 방법을 가장 작은 금액이 증가?

데이터 구조를 갖는 것으로 정의 마이크로초 단위로 측정하지만,그는 것을 의미하지 않는 시계 또는 운영 체제입니다 실제로 측정할 수 있는니다.

다른 사람들처럼,제안 gettimeofday() 이기 때문에 나쁜 시간을 설정할 수 있습생 시계를 왜곡하고 계산이 됩니다. clock_gettime(CLOCK_MONOTONIC) 당신이 원하는 무엇인가,그리고 clock_getres() 을 말할 것이다 당신의 정밀도는 시계.

실제의 해결책 gettimeofday()하드웨어에 의존하고 포함됩니다.인텔 프로세서 뿐만 아니라 SPARC 기계를 제공 높은 해상도의 타이머을 측정하는 마이크로초 단위로.다른 하드웨어 아키텍처 가을 다시 시스템의 타이머,일반적으로 설정하면 100Hz 입니다.그러한 경우에는 시간 해상도 정확도가 다소 떨어질 수 있습니다.

나 얻는 이 대답터 높은 해상도의 시간 측정 타이머,부 I

이 답변 언급한 문제가 시계는 조정됩니다.모두 당신의 문제를 보장하는 틱 장치 및 문제는 시간이 조정되는 해결된 C++11 <chrono> 라이브러리입니다.

시계 std::chrono::steady_clock 하지 않는 조정될고,또한 그것은 사전에 일정한 비율에 상대적인 실제 시간이다,그래서 같은 기술은 스피드스텝야에 영향을 미치지 않습니다.

당신이 얻을 수 있는 형식이 안전한 단위로 변환하여 중 하나 std::chrono::duration 전문 등 std::chrono::microseconds.이 유형이 없는 모호성에 대한 단위 사용하는 틱 값입니다.그러나 유지 하는 마음에 시계 없이 해상도입니다.로 변환할 수 있는 기간을 attoseconds 없이 실제로는 시계는 정확합니다.

내 경험에서,그리고 내가 읽은 인터넷을 통해 대답은"아니,"그것은 보장되지는 않습니다.에 따라 CPU 속도 운영,시스템,풍미의 리눅스 등

을 읽 RDTSC 지에서 믿을 수 있는 SMP 시스템므로,각각의 CPU 유지 자신의 카운터와 각각의 카운터 보장되지는 않으로 동기화와 관련하여 다른 CPU.

수하려고 제안 clock_gettime(CLOCK_REALTIME).Posix 수동을 나타내는 이야에서 구현되는 모두 준수하는 시스템입니다.을 제공할 수 있습 nanosecond 수 있지만,당신은 아마을 확인하는 것이 좋습니다 clock_getres(CLOCK_REALTIME) 시스템에서 무엇을 보고 실제적인 해결책입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top