백만분의 1초 까지 계산할 수 있을 까요?

andysheep의 이미지

clock() 함수로

while loop 를 한번은 500,000 번 돌게,

다음 한번은 600,000 번 돌게 한 후

걸린 시간을 비교해 보니 결과 값이 똑같게 나오네요.

0.01 초인가 한계인 듯 하네요.

glibc 매뉴얼에서 시간에 관한 부분을 보니

struct timeval 은 변수 중 하나가 백만분의 1초 값을 저장한다고 설명이 되었더군요. 근데, 제가 사용하는 시스템의 CPU는 샐래론 450MHz 입니다.

450 MHz 의미처럼 는 시스템이 1초에 450, 000, 000 클럭을 만들어 내고, 리눅스 커널에서 이 클럭수를 1/100 간격으로 얻어내 준다면 충분히 백만분의 1초까지 시간 차이를 얻어낼 수 있다고 봅니다.

dhunter의 이미지

보통 그런경우에는 루프회수를 좀 더 극적으로 늘려서 나눕니다만...

더 낮은 시간 단위의 함수가 일부 라이브러리에 있었을겁니다. 잘은 기억 안나는데;

from bzImage
It's blue paper

Necromancer의 이미지

man nanosleep

Written By the Black Knight of Destruction

warpdory의 이미지

일반적인 PC 하드웨어에선 거의 불가능합니다만, 몇몇 하드웨어를 추가하면 가능합니다. 속편하게 추가할 수 있는 범용장비중 하나가 GPIB 입니다. http://www.ni.com 가시면 사양을 볼 수 있습니다.


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

andysheep의 이미지

glibc랑 인터넷 검색 해서 간단하게(?) 만들어 봤습니다.

struct timeval 사용하면 마이크로초 (백만분의 1초) 단위로 시간 가져오는 것 같습니다.

예로,
current time: 2004 09 05 15:46:17.919181
current time: 2004 09 05 15:46:17.920041
는 while loop 안에서 한 루프 돌때마다 시간이 지난 결과입니다.

맨 아래 결과 보면 clock() 이용해서 CPU 시간차 가져온 값과
gettimeofday() 값의 차이를 보면 소숫점 3째자리 이하입니다.

/*
   sample-cpu-time.c
   2004/09/03 19:02 

   example of getting CPU time 
*/

#include <stdio.h>
#include <time.h>
#include <sys/time.h>

void do_something(const double limit);
void do_something2(void);
void elapsed_time(struct timeval start, struct timeval end);



void do_something(const double limit)
{
		clock_t start, end;
		double cpu_time_used;
		double i = 0;

		start = clock();
		while ( i++ < limit )
			;
		end = clock();

		cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

		printf("%f loop - elapsed time is %lf\n", limit, cpu_time_used);
}



void do_something2(void)
{
		int i; 
		struct timeval now;
		struct tm brokentime;
		char 	timestr[80];

		for (i = 0; i < 20; i++)
		{
				gettimeofday(&now, NULL);
				localtime_r (&now.tv_sec, &brokentime);
				strftime (timestr, sizeof(timestr), "%Y %m %d %T", &brokentime);
				printf("current time: %s.%d\n", timestr, now.tv_usec);
		}
}


void do_something3(const double limit)
{
		struct timeval start, end;
		double i = 0;

		gettimeofday(&start, NULL);
		while ( i++ < limit )
			;

		gettimeofday(&end, NULL);

		elapsed_time(start, end);
}


void elapsed_time(struct timeval start, struct timeval end)
{
		struct timeval et;

		if ( end.tv_usec < start.tv_usec )
		{
				end.tv_sec = end.tv_sec - 1;
				end.tv_usec = end.tv_usec + 1000000;
		}
		et.tv_sec = end.tv_sec - start.tv_sec;
		et.tv_usec = end.tv_usec - start.tv_usec;
		printf("elapsed time is %d.%06d\n", et.tv_sec, et.tv_usec);

		
}

int main()
{
		struct timeval start, end;
		struct timezone zone;
		double i = 0; 

		do_something(500000);
		do_something(1000000);

		do_something3(500000);
		do_something3(1000000);
		do_something3(8000000);
		do_something3(118000000);
		printf("Is it microsec?\n");
		do_something2();

		return 0;
}
		
/*
500000.000000 loop - elapsed time is 0.010000
1000000.000000 loop - elapsed time is 0.020000
elapsed time is 0.010263
elapsed time is 0.020312
elapsed time is 0.161543
elapsed time is 2.369592
Is it microsec?
current time: 2004 09 05 15:46:17.919181
current time: 2004 09 05 15:46:17.920041
current time: 2004 09 05 15:46:17.920075
current time: 2004 09 05 15:46:17.920104
current time: 2004 09 05 15:46:17.920147
current time: 2004 09 05 15:46:17.920180
current time: 2004 09 05 15:46:17.920208
current time: 2004 09 05 15:46:17.920247
current time: 2004 09 05 15:46:17.920273
current time: 2004 09 05 15:46:17.920298
current time: 2004 09 05 15:46:17.920349
current time: 2004 09 05 15:46:17.920379
current time: 2004 09 05 15:46:17.920407
current time: 2004 09 05 15:46:17.920432
current time: 2004 09 05 15:46:17.920459
current time: 2004 09 05 15:46:17.920487
current time: 2004 09 05 15:46:17.920519
current time: 2004 09 05 15:46:17.920548
current time: 2004 09 05 15:46:17.920577
current time: 2004 09 05 15:46:17.920605
*/

Devuan 1.0 (Debian without systemd)
amd64 station: AMD FX(tm)-6100 Six-Core Processor, 8 GB memory, 1 TB HDD
amd64 laptop: HP Touchsmart

글쇠판: 세벌 최종식, 콜맥 (Colemak)

andysheep의 이미지

akpil wrote:
일반적인 PC 하드웨어에선 거의 불가능합니다만, 몇몇 하드웨어를 추가하면 가능합니다. 속편하게 추가할 수 있는 범용장비중 하나가 GPIB 입니다. http://www.ni.com 가시면 사양을 볼 수 있습니다.

정보 감사합니다.

glibc를 사용해 리눅스에서 백만분의 1초 범위에서 시간 차를 소프트웨어적으로 보여주니까 일단 만족합니다. 진짜로 초정밀 시간이 필요한 하드웨어 관련 작업을 하면 특수한 계측기나 장비를 사용해야겠다는 생각이 드네요.

Devuan 1.0 (Debian without systemd)
amd64 station: AMD FX(tm)-6100 Six-Core Processor, 8 GB memory, 1 TB HDD
amd64 laptop: HP Touchsmart

글쇠판: 세벌 최종식, 콜맥 (Colemak)

aspilla의 이미지

X86 계열의 PC는 RDTSC를 이용하여 Tick을 Count할 수 있습니다.

회사에서 Benchmark 프로그램을 작성할때 이용했었는데 PC의 성능이 좋다면 1nano sec 정도의 resolution으로 time을 측정할 수 있습니다.

Win32환경이라면 QueryPerformanceCounter를 이용한 코드들이 널려 있겠지만 Linux환경이라면 코드를 좀 손보셔야 할겁니다.

구글에서 검색해 보세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.