装配CPU频率测量算法

时间:2020-03-05 18:54:06  来源:igfitidea点击:

用来测量处理器频率的常见算法有哪些?

解决方案

回答

我不确定为什么要为此组装。如果我们在具有/ proc文件系统的计算机上,请运行:

> cat /proc/cpuinfo

可能会给我们我们所需要的。

回答

这就是BogoMIPS之类的目的,但如今CPU变得更加复杂。超标量CPU可以每个时钟发出多个指令,从而基于计数时钟周期进行任何测量来执行高度不准确的指令块。

CPU频率也会根据提供的负载和/或者温度而变化。 CPU当前以800 MHz运行的事实并不意味着它将始终以800 MHz运行,它可能会根据需要加速或者减速。

如果我们确实需要知道时钟频率,则应将其作为参数传递。板上的EEPROM将提供基本频率,如果时钟变化,我们将需要能够读取CPU的电源状态寄存器(或者进行OS调用)以找出该时刻的频率。

综上所述,可能还有其他方法可以完成我们想要做的事情。例如,如果要对特定代码路径花费多长时间进行高精度测量,则CPU可能具有以固定频率运行的性能计数器,与读取滴答计数寄存器相比,该计数器更好地衡量了挂钟时间。

回答

Core Duo之后的Intel CPU支持两个特定于模型的寄存器,称为IA32_MPERF和IA32_APERF。
MPERF以CPU支持的最大频率计数,而APERF以实际当前频率计数。

实际频率由下式给出:

我们可以通过此流程阅读它们

; read MPERF
mov ecx, 0xe7
rdmsr
mov mperf_var_lo, eax
mov mperf_var_hi, edx

; read APERF
mov ecx, 0xe8
rdmsr
mov aperf_var_lo, eax
mov aperf_var_hi, edx

但请注意,rdmsr是特权指令,只能在环0中运行。

我不知道操作系统是否提供读取这些内容的接口,尽管它们的主要用途是电源管理,因此它可能不提供这样的接口。

回答

我将在这个答案中与各种细节约会,但是到底...

多年前,我不得不在基于Windows的PC上解决此问题,因此我正在处理Intel x86系列处理器,例如486,Pentium等。在这种情况下,标准算法是执行一系列DIVide指令,因为这些指令通常是Intel集中CPU最多的单个指令。因此,内存预取和其他体系结构问题不会严重影响指令的执行时间-预取队列始终为满,并且指令本身不会接触任何其他内存。

我们将使用可在运行环境中访问的最高分辨率时钟对其进行计时。(就我而言,我在兼容PC的启动时间附近运行,因此我直接在主板上对计时器芯片进行编程。建议在实际操作系统中使用,通常这些天通常有一些适当的API可以调用)。

我们必须处理的主要问题是不同的CPU类型。当时有英特尔,AMD和一些较小的供应商(如Cyrix)生产x86处理器。相对于DIV指令,每个模型都有其自己的性能特征。我的汇编计时功能只是返回一定数量的时钟周期,这些时钟周期由紧密循环中执行的一定数量的DIV指令占用。

因此,我要做的是从运行我想计时的每个处理器模型的实际PC上收集一些计时(该函数的原始返回值),并根据已知的处理器速度和处理器类型将这些计时记录在电子表格中。实际上,我有一个命令行工具,它只是计时功能的薄壳,我可以将磁盘放入计算机存储中,并从显示模型中获得计时! (当时我在一家非常小的公司工作)。

使用这些原始时序,我可以绘制一个理论图,说明在该特定CPU的任何已知速度下应该获得哪些时序。

这就是诀窍:我总是讨厌何时运行实用程序,并且它会宣布CPU为99.8 Mhz或者任何其他值。显然,它是100 Mhz,测量中的舍入误差很小。在我的电子表格中,我记录了每个处理器供应商出售的实际速度。然后,我将使用实际时序图来估计任何已知速度的预计时序。但是我会沿着时间线建立一个点表,在该点上计时应舍入到下一个速度。

换句话说,如果100次滴答作完所有重复的除法运算就意味着500 Mhz,而200次滴答就意味着250 Mhz,那么我将建立一个表,表示低于150的任何值为500 Mhz,高于250的任何值为250 Mhz。 (假设那是该芯片供应商仅有的两种速度)。很好,因为即使PC上有些奇怪的软件拖延了我的工作时间,但最终结果通常仍然无法实现。

当然,现在,在这些超频,用于电源管理的动态时钟速度以及其他类似技巧的日子里,这种方案将变得不那么实用。在运行计时功能之前,至少需要做一些事情来确保CPU首先处于其动态选择的最高速度。

好,我现在回去把孩子们赶出草坪。

回答

在AMD和Intel上的一个快速谷歌搜索显示CPUID应该可以让我们访问CPU的最大频率。

回答

" lmbench"提供了一种可移植到不同体系结构的cpu频率算法。

它运行一些不同的循环,并且处理器的时钟速度是各个循环执行频率的最大公约数。

当我们能够获得具有相对质数的循环计数的循环时,此方法应始终有效。

http://www.bitmover.com/lmbench/

回答

自奔腾以来,在x86 Intel CPU上使用的一种方法是使用RDTSC指令的两次采样,并使用已知的壁挂时间延迟循环,例如:

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>

uint64_t rdtsc(void) {
    uint64_t result;
    __asm__ __volatile__ ("rdtsc" : "=A" (result));
    return result;
}

int main(void) {
    uint64_t ts0, ts1;    
    ts0 = rdtsc();
    sleep(1);
    ts1 = rdtsc();    
    printf("clock frequency = %llu\n", ts1 - ts0);
    return 0;
}

(在具有GCC的32位平台上)

如果设置了CR4中的TSC标志,则RDTSC在环3中可用,这是常见的但不能保证。这种方法的一个缺点是,如果延迟发生在频率定标变化中,它很容易受到影响结果的影响。为了缓解这种情况,我们可以执行使CPU保持忙碌并不断轮询系统时间以查看延迟时间是否已到期的代码,以使CPU保持可用的最高频率状态。