C语言获取CPU主频并通过rdtsc获取系统时戳
#include<stdio.h>
#include<stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/time.h>
static unsigned long long rdtsc(void)
{
unsigned int low, high;
asm volatile ("rdtsc" : "=a"(low), "=d"(high) : );
return ((unsigned long long)high<<32) + (unsigned long long)low;
}
unsigned long long g_startRdtsc;
struct timeval g_tvStart;
unsigned long long g_cpuCyclesMhz;
unsigned long long getCpuCyclesMhz()
{
FILE *fp;
char cycleStr[128];
memset(cycleStr, 0, 128);
fp = popen("cat /proc/cpuinfo | grep MHz | uniq |sed -e 's/.*:[^0-9]//'","r");
if (fp<0) {
printf("Can't read CPU cycle info !!!\n");
exit(1);
}
fgets(cycleStr, 127, fp);
fclose(fp);
unsigned long long cycle = (unsigned long long)atof(cycleStr);
printf("CPU cycle : %llu MHz\n", cycle);
return cycle;
}
void myGettimeofday(struct timeval* tmValue)
{
unsigned long long tm = rdtsc();
tmValue->tv_sec = g_tvStart.tv_sec + (tm - g_startRdtsc)/(g_cpuCyclesMhz*1000000);
tmValue->tv_usec= g_tvStart.tv_usec + ((tm - g_startRdtsc)/g_cpuCyclesMhz) % 1000000);
}
int main()
{
unsigned long long tscStart[100], tscEnd[100];
unsigned long long wrapperStart[100], wrapperEnd[100];
struct timeval tvStart, tvEnd;
g_startRdtsc = rdtsc();
gettimeofday(&g_tvStart, NULL);
g_cpuCyclesMhz = getCpuCyclesMhz();
printf("Current machine cycles %llu\n", g_cpuCyclesMhz);
int i;
for (i = 0; i < 100; i++) {
tscStart[i] = rdtsc();
gettimeofday(&tvStart, NULL);
tscEnd[i] = rdtsc();
}
for (i = 0; i < 100; i++) {
wrapperStart[i] = rdtsc();
myGettimeofday(&tvStart);
wrapperEnd[i] = rdtsc();
}
for (i = 0; i < 100; i++) {
printf("cycles gettimeofday[%d] %d myGettimeofday %d\n", i, tscEnd[i] - tscStart[i], wrapperEnd[i] - wrapperStart[i]);
}
}
测试下优化效果几乎没有,主要耗时计算在乘除运算中,需要从使用角度优化;如果除了乘法运算,cycle耗时可以减半;

浙公网安备 33010602011771号