高精度(高解像度)な時刻の取得 (Linux, x64, C言語) 1
Linux と x64 CPU で,細かい(解像度が高い)時刻調査方法を説明します.
clock_gettime()
説明
解像度(resolution)は 1ns(ナノ秒, 10^-9秒) です.
使用方法
#include <stdio.h>
#include <time.h>
void main(){
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
printf("%ld.%09ld\n",ts.tv_sec,ts.tv_nsec);
}
使用例 と 実行例
#include <stdio.h>
#include <time.h>
#include <unistd.h>
void main(){
struct timespec ts0, ts1;
clock_gettime(CLOCK_REALTIME, &ts0);
sleep(2);
clock_gettime(CLOCK_REALTIME, &ts1);
printf("%ld.%09ld\n",ts0.tv_sec,ts0.tv_nsec);
printf("%ld.%09ld\n",ts1.tv_sec,ts1.tv_nsec);
}
実行結果
CLOCK_REALTIME以外でclock_gettime()
clock_gettime()は第1引数に clockid を指定します.
clockidとしては,以下のものを指定できます.
それぞれ解像度が異なります.
各clockidのresolution
解像度の調査方法
#include <stdio.h>
#include <time.h>
int clockid[11]={ CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_REALTIME_COARSE, CLOCK_TAI, CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID};
char clockidname[11][25]={"CLOCK_REALTIME", "CLOCK_REALTIME_ALARM", "CLOCK_REALTIME_COARSE", "CLOCK_TAI", "CLOCK_MONOTONIC", "CLOCK_MONOTONIC_COARSE", "CLOCK_MONOTONIC_RAW", "CLOCK_BOOTTIME", "CLOCK_BOOTTIME_ALARM", "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID"};
void main(){
struct timespec res;
int i;
for(i=0; i<11; i++){
if( ! clock_getres(clockid[i], &res) ){
printf("%s %ld%09ld ns\n", clockidname[i], res.tv_sec, res.tv_nsec);
}
}
}
調査結果
CLOCK_REALTIMEは 1 ns.CLOCK_REALTIME_COARSEは 4000000 ns
rdtsc命令
説明
解像度は 1 CPUクロックです.
使用方法
により取得可能です.
#include <stdio.h>
#define RDTSC(X) asm volatile ("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" : "=a" (X) :: "%rdx")
void main(){
long long int tsc;
RDTSC(tsc);
printf("%lld\n", tsc);
}
使用例 と 実行例
#include <stdio.h>
#include <unistd.h>
#define RDTSC(X) asm volatile ("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" : "=a" (X) :: "%rdx")
void main(){
long long int tsc0, tsc1;
RDTSC(tsc0);
sleep(2);
RDTSC(tsc1);
printf("%lld %lld %lld\n", tsc0, tsc1, tsc1-tsc0);
}
実行結果
gettimeofday()
説明
解像度は 1us(マイクロ秒, 10^-6秒) です.
使用方法
#include <stdio.h>
#include <sys/time.h>
void main(){
struct timeval tv;
gettimeofday( &tv, NULL);
printf("%ld.%06ld\n",tv.tv_sec, tv.tv_usec);
}
使用列 と 実行例
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
void main(){
struct timeval tv0, tv1;
gettimeofday( &tv0, NULL);
sleep(2);
gettimeofday( &tv1, NULL);
printf("%ld.%06l\n",tv0.tv_sec, tv0.tv_usec);
printf("%ld.%06l\n",tv1.tv_sec, tv1.tv_usec);
}
実行結果
コメント
gettimeofday() を使うのは辞めましょう。
とのことです。