Ho cercato di utilizzare un semplice profiler per misurare l'efficienza di alcuni codici C su un server scolastico, e sto colpendo una situazione strana. Dopo un breve periodo di tempo (mezzo secondo secondo), il processore inizia improvvisamente ad eseguire le istruzioni due volte più velocemente. Ho provato per quasi tutti i possibili motivi a cui potrei pensare (memorizzazione nella cache, bilanciamento del carico sui core, frequenza della CPU modificata a causa dell'esaurimento del sonno), ma tutto sembra normale.Perché la mia CPU improvvisamente funziona il doppio più velocemente?
Per quello che vale, sto facendo questo test su un server linux della scuola, quindi è possibile che ci sia una configurazione insolita che non conosco, ma l'ID del processore in uso non cambia, e (via top) il server era completamente inattivo come ho provato.
codiceprova:
#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);
}
}
uscita vedo:
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
ottengo un risultato simile (con esso prendendo un diverso numero di test per raddoppiare in termini di efficienza) con diversi livelli di ottimizzazione (-O0 a -O3).
Potrebbe forse avere qualcosa a che fare con l'hyperthreading, dove due core logici in un nucleo fisico (il server sta usando Xeon X5560s che può avere questo effetto) possono in qualche modo "unire" per formare un processore due volte più veloce?
Non è solo un evento comune della limitazione della CPU? – xbug
All'inizio pensavo che fosse la limitazione della CPU, ma sto calcolando il GHz da cicli/tempo ed è molto coerente a 2.793 (che è quello che/proc/cpuinfo riporta come velocità). Se la CPU fosse sottoposta a limitazioni, il valore non sarebbe dimezzato? – dooglius
Si dovrebbe leggere su 'Turbo Boost', che sono abbastanza sicuro è disponibile su quella CPU. – Petesh