我正在从一个线程发送网络数据包,并在另一个运行在不同CPU核心上的线程上接收回复.我的进程测量每个数据包的发送和接收之间的时间(类似于ping).我正在使用rdtsc来获得高分辨率,低开销的时序,这是我的实现所需要的.
所有测量看起来都很可靠.尽管如此,我仍然担心核心的rdtsc准确性,因为我一直在阅读一些暗示tsc未在核心之间同步的文本.
恒定的TSC行为可确保每个时钟周期的持续时间均匀,并支持将TSC用作挂钟定时器,即使处理器内核更改频率也是如此.这是所有英特尔处理器的架构行为.
我仍然担心核心的累积性,这是我的问题
我正在做一些Linux内核时序,特别是在中断处理路径中.我一直在使用RDTSC进行计时,但是我最近了解到它并不一定准确,因为指令可能无序发生.
然后我尝试了:
RDTSC + CPUID(在这里以相反的顺序)刷新管道,由于超级调用和诸如此类的原因,在虚拟机(我的工作环境)上产生高达60倍的开销(!).无论是否启用了HW Virtualization,都可以使用此功能.
最近我遇到了RDTSCP*指令,它看起来像RDTSC + CPUID那样做,但更高效,因为它是一个较新的指令 - 相对而言只有1.5x-2x的开销.
我的问题:RDTSCP作为一个测量点是否真的准确,它是做出时机的"正确"方法吗?
另外要明确一点,我的时间基本上就是这样,内部:
给定具有恒定TSC的x86 ,这对于测量实时非常有用,如何在启动时使用Linux计算的TSC校准因子在TSC参考周期的"单位"和正常人类实时单位(如纳秒)之间进行转换?
也就是说,当然可以通过CLOCK_MONOTONIC在某个时间间隔的两端进行TSC和时钟测量(例如,用)来计算用户区中的TSC频率,以确定TSC频率,但Linux已经在启动时进行了此计算,因为它内部使用TSC帮助进行计时.
例如,您可以通过以下方式查看内核的结果dmesg | grep tsc:
[ 0.000000] tsc: PIT calibration matches HPET. 2 loops
[ 0.000000] tsc: Detected 3191.922 MHz processor
[ 1.733060] tsc: Refined TSC clocksource calibration: 3192.007 MHz
Run Code Online (Sandbox Code Playgroud)
在更糟糕的情况下,我猜你可以尝试dmesg在运行时grep结果,但坦率地看起来很可怕,脆弱和各种各样的坏0.
使用内核确定的校准时间的优点很多:
cpuid叶片0x15 宣传其TSC频率,因此不一定需要进行校准)时,您会自动在TSC校准中获取新技术.gettimeofday和clock_gettime1)使用的TSC频率在某种程度上"一致" .然而,使用Linux的TSC校准的一些缺点包括:
0例如:系统可能没有dmesg安装,您可能无法以普通用户身份运行它,累积的输出可能已经缠绕,因此线路不再存在,您可能会在grep上获得误报,内核消息是英文散文,可能会有变化,可能很难启动子流程等等.
1这是否有争议 - 但如果您将rdtsc调用与使用OS时间保持的代码混合,则可能会提高精度.
我正在尝试编写一个可以读取msr寄存器的简单应用程序,并从用户空间运行此应用程序.
我已经加载了msr模块,并为每个人提供了对/ dev/cpu/*/msr的读取权限.但是仍然用户无法访问这些文件,但root可以.
权限如下所示:
crw-r--r-- 1 root root 202, 0 sep 6 17:55 /dev/cpu/0/msr
crw-r--r-- 1 root root 202, 1 sep 6 17:55 /dev/cpu/1/msr
crw-r--r-- 1 root root 202, 2 sep 6 17:55 /dev/cpu/2/msr
crw-r--r-- 1 root root 202, 3 sep 6 17:55 /dev/cpu/3/msr
Run Code Online (Sandbox Code Playgroud)
当我尝试从用户空间读取这些文件时,我一直收到"不允许操作"错误消息,但当root尝试访问它们时工作正常.我究竟做错了什么?我在Ubuntu 13.04上使用内核版本3.11.0.