用于基准测试和时间戳计数器频率的rdtsc的准确性

Cyg*_*nus 5 linux time assembly intel

作为基准测试任务的一部分,我正在研究可用于测量经过时间的不同机制.我已经完成了使用clock_gettime,但我也做了充分的研究和测试RDTSC.我有几个相同的问题(基于我在几个在线线程上读到的内容):

  • 在较新的处理器(> Pentium 4)上,TSC以系统上CPU的最大频率进行计时.它是否正确?在这种情况下,使用滴答数和频率来确定时间是否有效?

  • 如果以上情况属实,则意味着TSC不受由于省电和其他功能导致的CPU频率变化的影响.知道这一点,是否意味着通过使用获得的总滴答数RDTSC不是采样的代码段使用的实际滴答 - 因为代码将以CPU的频率而不是TSC的频率运行?此外,这是否意味着使用TSC滴答获得的时间和CPU频率不是代码片使用的实际时间?

  • 我发现了许多关于跨核心同步TSC值的不同陈述(参见本篇文章).我不确定什么是正确的,我猜这也取决于处理器型号.但是可以假设它在新CPU的内核之间同步吗?(这是没有用的sched_set_affinity)?

请注意,RDTSC由于与之相关的各种问题(便携性,可靠性等),我没有使用.这些问题只是为了提高我对TSC如何工作以及一般基准测试的理解.

har*_*old 5

根据英特尔的说法,不变的TSC意味着

不变的TSC将在所有ACPI P-,C-中以恒定速率运行。和T状态。

那是什么速率?好,

该速率可以由处理器的最大内核时钟与总线时钟之比设置,也可以由处理器启动时的最大解析频率设置。最大解析频率可能与处理器的最大合格频率有所不同,有关更多详细信息,请参见第18.14.5节。在某些处理器上,TSC频率可能与品牌字符串中的频率不同。

在我看来,他们好像希望它是品牌字符串中出现的频率,但后来却不总是那么正确。.但是,该频率是多少?

TSC,IA32_MPERF和IA32_FIXED_CTR2在平台的相同最大分辨频率下运行,该频率等于可扩展总线频率和最大分辨总线比的乘积。
对于基于Intel Core微体系结构的处理器,可扩展总线频率在(0CDH)的位字段MSR_FSB_FREQ [2:0]中进行编码,请参阅附录B,“特定于模型的寄存器(MSR)”。可以从以下位字段读取最大已解析总线比率:
如果禁用XE操作,则可以在MSR_PLATFORM_ID [12:8]中读取最大已解析总线比率。它对应于最大合格频率。
如果启用了XE操作,则最大解析总线比在MSR_PERF_STAT [44:40]中给出,它对应于BIOS配置的最大XE操作频率。

但这可能不是很有帮助。TL; DR,以编程方式找到TSC速率是一项艰巨的工作。您当然可以在自己的系统上轻松找到它,只需根据定时循环获得不准确的猜测,然后采用“有意义的最近数”即可。无论如何,这可能是品牌字符串中的数字。它已经在我测试过的所有系统上使用过,但是我还没有测试那么多。如果不是,那么它将有一些明显的差异,因此您一定会知道。

另外,这是否意味着通过使用TSC时钟和CPU频率获得的时间不是代码段所使用的实际时间?

是的,但是并没有失去所有希望,使用TSC滴答声获得的时间和TSC速率(如果您以某种方式知道)将给出实际时间。通常在这里会冒出很多关于不可靠性的FUD。是的,RDTSC没有序列化(但是您可以添加序列化指令)。RDTSCP正在序列化,但是在某些方面还不够(不能执行得太早,但是执行得太晚)。但这并不是您不能使用它们,您可以接受一个错误,或者阅读我在下面链接的论文。

但是是否可以假定它在更新的CPU的内核之间是同步的?

是的,不,也许-它将被同步,除非写入了TSC。谁知道,有人可能会这么做。无法控制 它也不会在不同的套接字之间同步。

最后,在基准测试的背景下,我真的不购买有关RDTSC(P)的FUD。您可以根据需要进行序列化,TSC是不变的,并且您知道速率,因为它是您的系统。其实也没有任何替代方法,它基本上高分辨率时间测量来源,最终其他所有结果最终都会使用。即使没有特殊的预防措施(但可以过滤数据),大多数基准测试的准确性和准确性也很好,如果您需要更多基准测试,请阅读如何在英特尔®IA-32和IA-64指令集体系结构上对代码执行时间进行基准测试,编写内核模块,这样他们就可以摆脱其他受到大量FUD,先占和中断影响的基准错误源。