作为基准测试任务的一部分,我正在调查可用于测量经过时间的不同机制。我已经完成了使用clock_gettime
的最终定稿,但我也使用RDTSC
指令进行了充分的研究和测试。我有几个相同的问题(基于我在几个在线主题上阅读的内容):
在较新的处理器(> Pentium 4)上,TSC以系统上CPU的最大频率进行计时。它是否正确?在这种情况下,使用滴答数和频率来确定时间是否有效?
如果以上情况属实,则表示由于节电和其他功能,TSC不受CPU频率变化的影响。知道这一点,是否意味着使用RDTSC
获得的总滴答数不是采样的代码段使用的实际滴答 - 因为代码将以CPU的频率而不是TSC的频率运行?另外,这是否意味着使用TSC刻度获得的时间和CPU频率不是代码片使用的实际时间?
我发现了很多关于跨核心同步TSC值的不同陈述(见this thread)。我不确定什么是正确的,我猜这也取决于处理器型号。但是可以假设它在新CPU的内核之间同步吗? (这不使用sched_set_affinity
)?
请注意,由于与其相关的各种问题(便携性,可靠性等),我没有使用RDTSC
。这些问题只是为了提高我对TSC如何工作以及一般基准测试的理解。
答案 0 :(得分:4)
不变的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是不变的,您知道速率,因为它是您的系统。也没有任何替代方案,它基本上是高分辨率时间测量的 来源,最终其他所有东西最终都会被使用。即使没有特殊的预防措施(但过滤了你的数据),大多数基准测试的准确性和精确度都很好,如果你需要更多,那么阅读How to Benchmark Code Execution Times on Intel® IA-32 and IA-64 Instruction Set Architectures,他们会写一个内核模块,这样他们就可以摆脱其他两个来源。基准错误受到大量FUD,抢占和中断的影响。