C에서의 최적의 타이밍 방법?
고해상도와 휴대성을 갖춘 코드 섹션의 시간을 재는 가장 좋은 방법은 무엇입니까?
/* Time from here */
ProcessIntenseFunction();
/* to here. */
printf("Time taken %d seconds %d milliseconds", sec, msec);
크로스 플랫폼 솔루션을 탑재할 수 있는 표준 라이브러리가 있습니까?
이 방법이 효과가 있을 것 같습니다.
#include <time.h>
clock_t start = clock(), diff;
ProcessIntenseFunction();
diff = clock() - start;
int msec = diff * 1000 / CLOCKS_PER_SEC;
printf("Time taken %d seconds %d milliseconds", msec/1000, msec%1000);
get time of day 는 시스템 클럭 해상도 내에서 정확한 시간을 마이크로초로 반환합니다.또한 SourceForge의 High Resens Timers 프로젝트를 체크할 수도 있습니다.
get time of day()는 아마 원하는 것을 할 것입니다.
인텔제 하드웨어를 사용하고 있는 경우는, CPU 의 리얼 타임 인스트럭션 카운터를 읽어내는 방법을 이하에 나타냅니다.프로세서가 부팅된 이후 실행된 CPU 사이클의 수를 알 수 있습니다.이 카운터는 아마도 퍼포먼스 측정에 사용할 수 있는 가장 세밀한 최소 오버헤드카운터일 것입니다.
이것은 CPU 사이클의 수라는 점에 주의해 주세요.Linux 에서는 /proc/cpuinfo 에서 CPU 속도를 취득하여 초수를 취득할 수 있습니다.이것을 더블로 변환하는 것은 매우 편리합니다.
내가 이걸 내 박스로 돌리면
1186792787948473211867927879692217printf : 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);
}
CPU의 시간을 필요로 하지 않는 경우는, 시간 구조라고 생각합니다.
실행 시간 계산에는 다음을 사용합니다.
int timeval_subtract(struct timeval *result,
struct timeval end,
struct timeval start)
{
if (start.tv_usec < end.tv_usec) {
int nsec = (end.tv_usec - start.tv_usec) / 1000000 + 1;
end.tv_usec -= 1000000 * nsec;
end.tv_sec += nsec;
}
if (start.tv_usec - end.tv_usec > 1000000) {
int nsec = (end.tv_usec - start.tv_usec) / 1000000;
end.tv_usec += 1000000 * nsec;
end.tv_sec -= nsec;
}
result->tv_sec = end.tv_sec - start.tv_sec;
result->tv_usec = end.tv_usec - start.tv_usec;
return end.tv_sec < start.tv_sec;
}
void set_exec_time(int end)
{
static struct timeval time_start;
struct timeval time_end;
struct timeval time_diff;
if (end) {
gettimeofday(&time_end, NULL);
if (timeval_subtract(&time_diff, time_end, time_start) == 0) {
if (end == 1)
printf("\nexec time: %1.2fs\n",
time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f));
else if (end == 2)
printf("%1.2fs",
time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f));
}
return;
}
gettimeofday(&time_start, NULL);
}
void start_exec_timer()
{
set_exec_time(0);
}
void print_exec_timer()
{
set_exec_time(1);
}
SDL 라이브러리의 SDL_GetTicks를 사용하고 있습니다.
고해상도는 상대적인...예시를 보고 있었는데 대부분 몇 밀리초 동안만 사용할 수 있습니다.다만, 저는 마이크로초를 측정하는 것이 중요합니다.플랫폼에 의존하지 않는 솔루션을 마이크로초 동안 본 적이 없기 때문에 아래 코드와 같은 것이 도움이 될 것이라고 생각했습니다.당분간은 윈도에서만 시간을 쟀는데 AIX/Linux에서 같은 작업을 할 때 gettimeofday() 구현을 추가할 가능성이 높습니다.
#ifdef WIN32
#ifndef PERFTIME
#include <windows.h>
#include <winbase.h>
#define PERFTIME_INIT unsigned __int64 freq; QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq); unsigned __int64 startTime; unsigned __int64 endTime; double timeDifferenceInMilliseconds;
#define PERFTIME_START QueryPerformanceCounter((LARGE_INTEGER *)&startTime);
#define PERFTIME_END QueryPerformanceCounter((LARGE_INTEGER *)&endTime); timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency); printf("Timing %fms\n",timeDifferenceInMilliseconds);
#define PERFTIME(funct) {unsigned __int64 freq; QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq); unsigned __int64 startTime; QueryPerformanceCounter((LARGE_INTEGER *)&startTime); unsigned __int64 endTime; funct; QueryPerformanceCounter((LARGE_INTEGER *)&endTime); double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency); printf("Timing %fms\n",timeDifferenceInMilliseconds);}
#endif
#else
//AIX/Linux gettimeofday() implementation here
#endif
사용방법:
PERFTIME(ProcessIntenseFunction());
or
PERFTIME_INIT
PERFTIME_START
ProcessIntenseFunction()
PERFTIME_END
언급URL : https://stackoverflow.com/questions/459691/best-timing-method-in-c
'programing' 카테고리의 다른 글
계산된 속성을 효과적으로 사용하는 Vue (0) | 2022.08.16 |
---|---|
Quasar QTable에 반영되지 않은 vuex 데이터 변경 사항 (0) | 2022.08.16 |
Linux 커널 코드에서 __init은 무엇을 의미합니까? (0) | 2022.08.16 |
사용자 지정 지시문에서 v-if 지시문 시뮬레이션 (0) | 2022.08.16 |
행/하위 구조를 사용한 루프 (0) | 2022.08.16 |