首页 > 系统相关 >linux下获取高精度时间

linux下获取高精度时间

时间:2022-12-05 16:23:10浏览次数:38  
标签:ptm testtm 高精度 linux 获取 内核 time cpu localtime

在linux下有很多获取时间的函数,不过大部分都是需要调用内核,对于性能要求非常高的程序可能无法满足要求,需要特殊的方法替代常见的api。

time localtime

time函数,获取从1970到现在的秒数,精确度只有秒,通过localtime转换

time_t testtm;
time(&testtm);
testtm = time(NULL);
struct tm *ptm ;
ptm = localtime(&testtm);
struct tm ptm = { 0 }; 
localtime_r(&testtm, &ptm); 

localtime不是线程安全的,后来增加了新函数localtime_r用来多线程之间使用,是线程安全的。localtime是不可重入的,多次调用会被覆盖。从其返回值也可以看出,localtime返回一个指针,所以这个指针的数据存储就成了大问题,导致多线程访问同一个,多次调用会覆盖。而localtime_r传递一个结构体,会帮你复制,就没有相互影响的问题。所以不要用localtime就对了,避免各种意想不到的问题。

不可以在信号响应函数中使用localtime或localtime_r,会导致卡死

clock_gettime

这个可以返回纳秒级别的数据,并且可以返回具体的系统时间(也是从1970年到现在的秒数)或者系统从开机开始到现在的运行时间。

struct timespec mtime;
clock_gettime(CLOCK_MONOTONIC, &mtime);
tm nowTime;
localtime_r(&mtime.tv_sec, &nowtime);

CLOCK_REALTIME和CLOCK_MONOTONIC分别对应是具体时间,还是机器运行时间。

rdtsc

rdtsc是cpu运行周期计数,只在Intel的x86_64架构上才可以使用,其他的cpu架构请查询其他用法。这个数值与cpu的频率有关,1Ghz等于十亿赫兹(1,000,000,000 Hz),表示1秒中计数增加十亿次。

uint64_t get_tsc()
{
    uint64_t mlow, mhigh;
    __asm__ volatile("rdtsc" : "=a"(mlow), "=d"(mhigh));
    return (mhigh << 32) | mlow;
}

这个方法会通过汇编,把当前cpu计数(64位)高32位存放到一个寄存器,低32位存放到另一个寄存器,我们取出后使用。
记住,如果自己修改,汇编那一行=a和=d是不可以变的,只能替换我们定义的变量mlow和mhigh名称。

这个方式不仅性能好,而且精度高,因为其没有经过内核,比上面的clock_gettime性能要好,不过比time localtime差一点,毕竟time localtime的精度太低了。

需要注意的问题

rdtsc是针对cpu运行频率的,但是同一个电脑上的cpu,不同内核,可能cpu频率并不一致,所以这个值最好不要跨cpu内核使用
其次,同一个cpu内核,不同时间,其频率也会变化,所以需要锁定cpu的频率

标签:ptm,testtm,高精度,linux,获取,内核,time,cpu,localtime
From: https://www.cnblogs.com/studywithallofyou/p/16952615.html

相关文章

  • Linux就该这么学-新手必须掌握的 Linux 命令
    执行查看帮助命令命令名称[命令参数][命令对象]man--helpman-hecho命令echoLinuxprobe.Comdate命令[root@linuxprobe~]#dateMonAug2416:11:23......
  • linux信号机制(初识版)
    转载 https://www.zhihu.com/question/24913599/answer/2584544572  信号是操作系统内核为我们提供用于在进程间通信的机制,内核可以利用信号来通知进程,当前系统所发......
  • JS获取数组中元素的最大值
    方法1:Math.max.apply()Math.max()方法默认接收多个参数并返回最大值,而apply()方法接收一个数组,将数组中的每一项作为参数传给调用函数,搭配使用可以得到最大值。const......
  • sheet.getLastRowNum()获取行数不准的问题
    //获得总共有多少行introwNum=0;//存在样式的空行。会被统计进来。所以主要的问题是要判断是否是空行。for(intnum=1;num<=sheet.getLastRowNum();num++){//......
  • python中ImmutableMultiDict嵌套字典的值获取和解决400状态码的问题
    在写接口的过程中遇到了一次请求状态码400原因是用elementupload组件上传照片,后端采用flask的时候用request.form读取上传携带的其他参数,data=request.formtitle=......
  • Linux 防火墙,端口操作
    1、开放关闭端口firewall-cmd--zone=public--add-port=5672/tcp--permanent#开放5672端口firewall-cmd--zone=public--remove-port=5672/tcp--permanent#关闭56......
  • linux下动态链接库(.so)的显式调用和隐式调用
    linux下动态链接库(.so)的显式调用和隐式调用2021-12-21进入主题前,先看看两点预备知识。一、显式调用和隐式调用的区别      我们知道,动态库相比静态库的区......
  • 获取网易云音乐开放接口api的推荐歌单
    网易云音乐开放api接口网址:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi项目地址:https://github.com/Binaryify/NeteaseCloudMusicAp......
  • Linux知识结构体系简述
    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。严格来讲,Linux 这个词本身只表......
  • Linux操作系统之tcpdump抓包工具详解
    前言①tcpdump工具简介:tcpdump是Linux操作系统中的字符界面的数据抓包分析软件。tcpdump可以将网络中传送的数据包完全截获下来提供分析②tcpdump是一个用于截取网络分组,并......