为什么我的CPU突然以两倍的速度工作?

doo*_*ius 6 c performance cpu-architecture

我一直在尝试使用一个简单的分析器来测量学校服务器上某些C代码的效率,而且我遇到了一个奇怪的情况.在很短的时间(半秒)之后,处理器突然开始执行指令两倍的速度.我已经测试了几乎我能想到的每一个可能的原因(缓存,核心负载平衡,CPU频率因睡眠不足而改变),但一切看起来都很正常.

为了它的价值,我正在学校的Linux服务器上进行这项测试,所以有可能是一个我不知道的不寻常的配置,但是使用的处理器ID没有改变,并且(通过顶部)服务器是我测试时完全闲置.

测试代码:

#include <time.h>
#include <stdio.h>

#define MY_CLOCK CLOCK_MONOTONIC_RAW
// no difference if set to CLOCK_THREAD_CPUTIME_ID

typedef struct {
        unsigned int tsc;
        unsigned int proc;
} ans_t;

static ans_t rdtscp(void){
        ans_t ans;
        __asm__ __volatile__ ("rdtscp" : "=a"(ans.tsc), "=c"(ans.proc) : : "edx");
        return ans;
}

static void nop(void){
        __asm__ __volatile__ ("");
}

void test(){
        for(int i=0; i<100000000; i++) nop();
}

int main(){
        int c=10;
        while(c-->0){
                struct timespec tstart,tend;
                ans_t start = rdtscp();
                clock_gettime(MY_CLOCK,&tstart);
                test();
                ans_t end = rdtscp();
                clock_gettime(MY_CLOCK,&tend);
                unsigned int tdiff = (tend.tv_sec-tstart.tv_sec)*1000000000+tend.tv_nsec-tstart.tv_nsec;
                unsigned int cdiff = end.tsc-start.tsc;
                printf("%u cycles and %u ns (%lf GHz) start proc %u end proc %u\n",cdiff,tdiff,(double)cdiff/tdiff,start.proc,end.proc);
        }
}
Run Code Online (Sandbox Code Playgroud)

输出我看到:

351038093 cycles and 125680883 ns (2.793091 GHz) start proc 14 end proc 14
350911246 cycles and 125639359 ns (2.793004 GHz) start proc 14 end proc 14
350959546 cycles and 125656776 ns (2.793001 GHz) start proc 14 end proc 14
351533280 cycles and 125862608 ns (2.792992 GHz) start proc 14 end proc 14
350903833 cycles and 125636787 ns (2.793002 GHz) start proc 14 end proc 14
350924336 cycles and 125644157 ns (2.793002 GHz) start proc 14 end proc 14
349827908 cycles and 125251782 ns (2.792997 GHz) start proc 14 end proc 14
175289886 cycles and 62760404 ns (2.793001 GHz) start proc 14 end proc 14
175283424 cycles and 62758093 ns (2.793001 GHz) start proc 14 end proc 14
175267026 cycles and 62752232 ns (2.793001 GHz) start proc 14 end proc 14
Run Code Online (Sandbox Code Playgroud)

我使用不同的优化级别(-O0到-O3)得到类似的输出(使用不同数量的测试以使效率加倍).

它是否可能与超线程有关,其中物理核心中的两个逻辑核心(服务器使用可能具有此效果的Xeon X5560)可以某种方式"合并"以形成一个两倍快的处理器?

use*_*542 0

有些 CPU 在芯片上进行了优化,可以学习代码通常采用的路径。通过成功预测下一个 if 语句将执行的操作,无需丢弃队列,并从头开始重新加载所有新操作。根据芯片和算法的不同,可能需要 5 到 10 个周期才能成功预测 if 语句。但不知怎的,也有一些理由反对这种行为的原因。

看看你的输出,我想说这也可能只是操作系统和/或那里使用的 CPU 频率调节器的调度。您确定 CPU 频率在代码执行期间不会改变吗?CPU没有提升?使用 cpufreq 等 Linux 工具经常用于调节 cpu 频率。

  • 这里涉及的时间范围太大,不可能是分支预测的产物。需要数百万个周期才能“锁定”的分支预测器毫无用处。 (7认同)