测量 CPU 时钟速度
Measuing CPU clock speed
我正在尝试测量 CPU.I 的速度,我不确定我的方法有多准确。基本上,我尝试了一个空的 for
循环,其值类似于 UINT_MAX
但程序很快终止,所以我尝试了 UINT_MAX * 3 等等...
然后我意识到编译器正在优化循环,所以我添加了一个 volatile
变量来防止优化。以下程序大约需要 1.5 秒才能完成。我想知道这种测量时钟速度的算法有多准确。另外,我怎么知道有多少核心参与了这个过程?
#include <iostream>
#include <limits.h>
#include <time.h>
using namespace std;
int main(void)
{
volatile int v_obj = 0;
unsigned long A, B = 0, C = UINT32_MAX;
clock_t t1, t2;
t1 = clock();
for (A = 0; A < C; A++) {
(void)v_obj;
}
t2 = clock();
std::cout << (double)(t2 - t1) / CLOCKS_PER_SEC << std::endl;
double t = (double)(t2 - t1) / CLOCKS_PER_SEC;
unsigned long clock_speed = (unsigned long)(C / t);
std::cout << "Clock speed : " << clock_speed << std::endl;
return 0;
}
好的优化器可能会消除循环,因为
for (A = 0; A < C; A++) {
(void)v_obj;
}
对程序状态的影响与;
相同
A = C;
因此优化器可以完全自由地解除循环。
因此您不能以这种方式测量 CPU 速度,因为它对编译器的依赖程度与对计算机的依赖程度一样高(更不用说已经提到的可变时钟速度和多核架构)
这根本不测量时钟速度,它测量每秒可以完成多少次循环迭代。没有规则说每个时钟周期一次迭代 运行 。 可能是这种情况,你可能实际上已经发现了这种情况 - 当然使用优化的代码和合理的CPU,一个无用的循环不应该运行 比那慢得多。虽然它可以 运行 以一半的速度运行,但某些处理器每 2 个周期不能退出超过 1 个采用的分支。在深奥的目标上,所有的赌注都落空了。
所以不,这不会测量时钟周期,除非是意外。一般来说,很难获得经验时钟速度(你可以问你的 OS 它认为最大时钟速度和当前时钟速度是多少,见下文),因为
如果您测量一个循环需要多少挂钟时间,您必须知道(至少大约)每次迭代的周期数。这在汇编中是一个足够糟糕的问题,需要对预期的微体系结构有相当详细的了解(可能是一长串依赖指令,每个指令只能合理地占用一个周期,比如 add eax, 1
?足够长的链使得 test/branch 吞吐量变得小到可以忽略),所以很明显你在那里做的任何事情都是不可移植的,并且内置的假设可能会变成错误的(实际上在 SO 上还有另一个答案这样做并假设 addps
延迟为 3,它在 Skylake 上不再存在,在旧的 AMD 上也没有)。在 C 中?现在放弃。编译器可能正在滚动一些随机代码生成器,并且依赖它是合理的就像对熊做同样的事情一样。猜测你无法控制甚至不知道的 代码每次迭代的周期数 是愚蠢的。如果它只是在你自己的机器上,你可以检查代码,但是你也可以手动检查时钟速度所以..
如果您测量在给定的挂钟时间内流逝的时钟周期数..但这很棘手。因为 rdtsc
不测量时钟周期(不再测量),而且没有其他更接近。您可以测量 something,但使用频率缩放和 Turbo,它通常不会是实际的时钟周期。您可以从性能计数器获得 actual 时钟周期,但您不能从用户模式执行此操作。显然,您尝试执行此操作的任何方式都是不可移植的,因为您不能可移植地询问经过的时钟周期数。
因此,如果您这样做是为了获取实际信息,而不是为了四处乱逛,您可能应该直接询问 OS。对于 Windows,向 WMI 查询 CurrentClockSpeed 或 MaxClockSpeed,无论您想要哪个。 Linux /proc/cpuinfo
上有内容。仍然不可移植,但是,没有解决方案。
至于
how do I know how many core's are being involved in the process?
1。当然你的线程可能会在核心之间迁移,但由于你只有一个线程,它在任何时候都只在一个核心上。
我正在尝试测量 CPU.I 的速度,我不确定我的方法有多准确。基本上,我尝试了一个空的 for
循环,其值类似于 UINT_MAX
但程序很快终止,所以我尝试了 UINT_MAX * 3 等等...
然后我意识到编译器正在优化循环,所以我添加了一个 volatile
变量来防止优化。以下程序大约需要 1.5 秒才能完成。我想知道这种测量时钟速度的算法有多准确。另外,我怎么知道有多少核心参与了这个过程?
#include <iostream>
#include <limits.h>
#include <time.h>
using namespace std;
int main(void)
{
volatile int v_obj = 0;
unsigned long A, B = 0, C = UINT32_MAX;
clock_t t1, t2;
t1 = clock();
for (A = 0; A < C; A++) {
(void)v_obj;
}
t2 = clock();
std::cout << (double)(t2 - t1) / CLOCKS_PER_SEC << std::endl;
double t = (double)(t2 - t1) / CLOCKS_PER_SEC;
unsigned long clock_speed = (unsigned long)(C / t);
std::cout << "Clock speed : " << clock_speed << std::endl;
return 0;
}
好的优化器可能会消除循环,因为
for (A = 0; A < C; A++) {
(void)v_obj;
}
对程序状态的影响与;
相同A = C;
因此优化器可以完全自由地解除循环。
因此您不能以这种方式测量 CPU 速度,因为它对编译器的依赖程度与对计算机的依赖程度一样高(更不用说已经提到的可变时钟速度和多核架构)
这根本不测量时钟速度,它测量每秒可以完成多少次循环迭代。没有规则说每个时钟周期一次迭代 运行 。 可能是这种情况,你可能实际上已经发现了这种情况 - 当然使用优化的代码和合理的CPU,一个无用的循环不应该运行 比那慢得多。虽然它可以 运行 以一半的速度运行,但某些处理器每 2 个周期不能退出超过 1 个采用的分支。在深奥的目标上,所有的赌注都落空了。
所以不,这不会测量时钟周期,除非是意外。一般来说,很难获得经验时钟速度(你可以问你的 OS 它认为最大时钟速度和当前时钟速度是多少,见下文),因为
如果您测量一个循环需要多少挂钟时间,您必须知道(至少大约)每次迭代的周期数。这在汇编中是一个足够糟糕的问题,需要对预期的微体系结构有相当详细的了解(可能是一长串依赖指令,每个指令只能合理地占用一个周期,比如
add eax, 1
?足够长的链使得 test/branch 吞吐量变得小到可以忽略),所以很明显你在那里做的任何事情都是不可移植的,并且内置的假设可能会变成错误的(实际上在 SO 上还有另一个答案这样做并假设addps
延迟为 3,它在 Skylake 上不再存在,在旧的 AMD 上也没有)。在 C 中?现在放弃。编译器可能正在滚动一些随机代码生成器,并且依赖它是合理的就像对熊做同样的事情一样。猜测你无法控制甚至不知道的 代码每次迭代的周期数 是愚蠢的。如果它只是在你自己的机器上,你可以检查代码,但是你也可以手动检查时钟速度所以..如果您测量在给定的挂钟时间内流逝的时钟周期数..但这很棘手。因为
rdtsc
不测量时钟周期(不再测量),而且没有其他更接近。您可以测量 something,但使用频率缩放和 Turbo,它通常不会是实际的时钟周期。您可以从性能计数器获得 actual 时钟周期,但您不能从用户模式执行此操作。显然,您尝试执行此操作的任何方式都是不可移植的,因为您不能可移植地询问经过的时钟周期数。
因此,如果您这样做是为了获取实际信息,而不是为了四处乱逛,您可能应该直接询问 OS。对于 Windows,向 WMI 查询 CurrentClockSpeed 或 MaxClockSpeed,无论您想要哪个。 Linux /proc/cpuinfo
上有内容。仍然不可移植,但是,没有解决方案。
至于
how do I know how many core's are being involved in the process?
1。当然你的线程可能会在核心之间迁移,但由于你只有一个线程,它在任何时候都只在一个核心上。