我在具有三种不同频率的三台不同计算机上分析一些代码。我需要频率来测量GFLOPs / s。我有一些代码可以做到这一点,但它不考虑Turboboost。例如,在我的2600k CPU上报告3.4 GHz,但我可以看到当我运行CPUz时,我的CPU运行在4.3 GHz(超频),因为我的代码使用了所有内核。
#include "stdint.h"
#include "stdio.h"
#include "omp.h"
int main() {
int64_t cycles = rdtsc(); double dtime = omp_get_wtime();
//run some code which uses all cores for a while (few ms)
dtime = omp_get_wtime() - dtime;
cycles = rdtsc() - cycles;
double freq = (double)cycles/dtime*1E-9;
printf("freq %.2f GHz\n", freq);
}
__int64 rdtsc() {
#ifdef _WIN32
return __rdtsc();
#else
uint64_t t;
asm volatile ("rdtsc" : "=A"(t));
return t;
#endif
}
我知道这个问题已经被各种各样的答案提出了各种答案,但我仍然不清楚是否可以这样做。我不关心黑客试图改变计时器。此代码仅适用于我自己。是否有可能在代码中获得实际频率?这是如何在Linux上完成的?我在linux上找到的每个例子都给出了基本频率(或者可能是最大值),而不是像CPUz那样负载下的工作频率。
编辑: 我找到了一个用于Linux的程序Powertop,它似乎显示了实际的工作频率。由于源代码可用,因此可以在我自己的代码中找出如何获得实际频率。
答案 0 :(得分:0)
我终于解决了这个问题。无需设备驱动程序或读取特殊计数器,即可在代码中测量实际工作频率。
基本上,你为一个带有循环依赖的操作设置一个循环,它总是需要相同的延迟。例如
for(int i=0; i<spinCount; i++) {
x = _mm_add_ps(x,_mm_set1_ps(1.0f));
}
在绑定到每个物理核心(非逻辑)核心的线程中运行此循环。要求系统中没有其他线程,然后这些线程需要占用大量的CPU时间,因此这种方法不会总是给出正确的答案,但在我的情况下它运行得很好。我得到的结果偏离一个线程的正确turbo频率低于0.5%,而单个插座系统和多插槽系统上的Nahalem,Ivy Bridge和Haswell的许多线程的结果偏差小于0.5%。我在how-can-i-programmatically-find-the-cpu-frequency-with-c描述了这个细节,所以我不会在这里重复所有细节。