I am trying to measure the speed of the CPU.I am not sure how much my method is accurate. Basicly, I tried an empty for
loop with values like UINT_MAX
but the program terminated quickly so I tried UINT_MAX * 3 and so on...
Then I realized that the compiler is optimizing away the loop, so I added a volatile
variable to prevent optimization. The following program takes 1.5 seconds approximately to finish. I want to know how accurate is this algorithm for measuring the clock speed. Also,how do I know how many core's are being involved in the process?
#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;
}
答案 0 :(得分:2)
这根本不测量时钟速度,它测量每秒可以完成的循环迭代次数。没有规则说每个时钟周期会运行一次迭代。 可能就是这种情况,你可能实际上已经发现它是这种情况 - 当然使用优化的代码和合理的CPU,无用的循环运行速度应该不会慢得多。它可以以半速运行,但是有些处理器不能每2个周期退出超过1个分支。在深奥的目标上,所有的赌注都没有了。
所以不,除了意外之外,这不会测量时钟周期。一般来说,获得经验时钟速度非常困难(你可以向你的操作系统询问它认为的最大时钟速度和当前时钟速度,见下文),因为
如果您测量一个循环占用的挂钟时间,您必须知道(至少近似)每次迭代的循环次数。这在组装中是一个非常糟糕的问题,需要对预期的微架构进行相当详细的了解(可能是一长串依赖指令,每个指令只能合理地占用1个周期,如add eax, 1
?足够长的链条,测试中的差异/分支吞吐量变小到可以忽略不计),所以你在那里做的任何东西都是不可移植的,并且内置的假设可能会变错(实际上在SO上还有另一个答案,并且假设addps
有一个延迟为3,它在Skylake上不再存在,并且没有旧的AMD)。在C?现在放弃。编译器可能正在滚动一些随机代码生成器,并且依赖它是合理的就像对熊做同样的事情。猜测每次迭代代码的周期数,你既不能控制也不知道就是愚蠢的。如果它只是在你自己的机器上你可以检查代码,但你也可以手动检查时钟速度,所以..
如果您测量在给定的挂钟时间内经过的时钟周期数,但这很棘手。因为rdtsc
不会测量时钟周期(不再是),所以没有其他任何东西可以更接近。您可以测量某些东西,但是通过频率缩放和turbo,它通常不会是实际的时钟周期。您可以从性能计数器获得实际时钟周期,但不能从用户模式执行此操作。显然,你尝试这样做的任何方式都不是便携式的,因为你不能轻易地询问经过的时钟周期数。
因此,如果你这样做是为了获取实际信息,而不仅仅是乱七八糟,那么你应该问问操作系统。对于Windows,查询WLC for CurrentClockSpeed或MaxClockSpeed,无论您想要哪个。在Linux上有/proc/cpuinfo
中的内容。仍然不便携,但是,没有解决方案。
至于
我怎么知道这个过程涉及多少核心?
1。当然,您的线程可能会在核心之间进行迁移,但由于您只有一个线程,因此它随时只能在一个核心上运行。
答案 1 :(得分:0)
一个好的优化器可能会删除循环,因为
for (A = 0; A < C; A++) {
(void)v_obj;
}
对程序状态的影响与;
相同A = C;
因此优化器可以完全自由地展开循环。
所以你不能用这种方式测量CPU速度,因为它依赖于编译器和计算机上的速度(更不用说已经提到的可变时钟速度和多核架构)