Domanda

In Win32, c'è un modo per ottenere un conteggio unico del ciclo della CPU o qualcosa di simile che sarebbe uniforme per più processi / lingue / sistemi / ecc.

Sto creando alcuni file di registro, ma devo produrre più file di registro perché stiamo ospitando il runtime .NET e vorrei evitare di chiamare dall'uno all'altro per accedere. In quanto tale, stavo pensando di produrre solo due file, combinarli e quindi ordinarli, per ottenere una sequenza temporale coerente che includesse chiamate tra paesi.

Tuttavia, GetTickCount non aumenta per ogni chiamata, quindi non è affidabile. C'è un numero migliore, in modo che le chiamate siano nell'ordine giusto durante l'ordinamento?


Modifica : grazie a @Greg che mi hanno messo sulla buona strada per QueryPerformanceCounter , che ha fatto il trucco.

È stato utile?

Soluzione

Puoi utilizzare le RDTSC istruzione CPU (presupponendo x86). Questa istruzione fornisce il contatore del ciclo della CPU, ma tieni presente che aumenterà molto rapidamente al suo valore massimo, quindi reimposta su 0. Come menzionato nell'articolo di Wikipedia, potresti essere meglio usando funzione QueryPerformanceCounter .

Altri suggerimenti

Ecco un articolo interessante! dice di non usare RDTSC, ma di usa invece QueryPerformanceCounter .

Conclusione:

  

Usare il vecchio timeGetTime() normale per fare   il tempismo non è affidabile su molti   Sistemi operativi basati su Windows   perché la granularità del sistema   il timer può arrivare fino a 10-15   millisecondi, nel senso che   timeBeginPeriod(1) è solo preciso   10-15 millisecondi. [Si noti che il   granularità elevate si verificano su base NT   sistemi operativi come Windows NT,   2000 e XP. Windows 95 e 98 tendono   avere una granularità molto migliore,   circa 1-5 ms.]

     

Tuttavia, se chiami   timeEndPeriod(1) all'inizio di   il tuo programma (e Sleep() a   alla fine), Sleep(1) di solito   diventare accurato di 1-2 millisecondi,   e ti fornirà estremamente   informazioni precise sui tempi.

     

Sleep(2) si comporta in modo simile; la lunghezza   di tempo che QueryPerformanceFrequency dorme effettivamente   perché va di pari passo con il   granularità di QueryPerformanceCounter, quindi dopo   chiamando <=> una volta,   <=> dormirà effettivamente per 1-2   millisecondi, <=> per 2-3 e così via   acceso (invece di dormire con incrementi   fino a 10-15 ms).

     

Per tempi più precisi   (precisione inferiore al millisecondo), lo farai   probabilmente voglio evitare di usare il   assemblaggio RDTSC mnemonico perché lo è   difficile da calibrare ; invece, usa   <=> e   <=>, che sono   preciso a meno di 10 microsecondi   (0,00001 secondi).

     

Per un tempismo semplice, entrambi timeGetTime   e QueryPerformanceCounter funzionano bene,   e QueryPerformanceCounter è   ovviamente più preciso. Tuttavia, se   devi fare qualsiasi tipo di " cronometrato   pause quot &; (come quelli necessari per   framerate limiting), devi esserlo   attento a stare seduto in un loop chiamando   QueryPerformanceCounter, in attesa di   per raggiungere un certo valore; questo sarà   consumare il 100% del tuo processore.   Invece, considera uno schema ibrido,   dove chiami Sleep (1) (non dimenticare   timeBeginPeriod (1) prima!) ogni volta   devi superare più di 1 ms di   ora, quindi immettere solo il   QueryPerformanceCounter loop 100% occupato   per finire l'ultimo < 1/1000 di a   secondo del ritardo necessario. Questo   ti darà ritardi estremamente precisi   (preciso a 10 microsecondi), con   utilizzo della CPU molto minimo. Vedi il codice   sopra.

System.Diagnostics.Stopwatch.GetTimestamp () restituisce il numero di cicli della CPU da un'origine temporale (forse all'avvio del computer, ma non sono sicuro) e non l'ho mai visto aumentare tra 2 chiamate.

I cicli della CPU saranno specifici per ciascun computer, quindi non è possibile utilizzarlo per unire il file di registro tra 2 computer.

L'uscita RDTSC può dipendere dalla frequenza di clock del core corrente, che per le CPU moderne non è né costante né, in una macchina multicore, coerente.

Utilizza l'ora di sistema e, se hai a che fare con feed di più sistemi, usa un'origine temporale NTP. In questo modo è possibile ottenere letture del tempo affidabili e coerenti; se il sovraccarico è eccessivo per i tuoi scopi, utilizzando HPET per calcolare il tempo trascorso dal l'ultima lettura affidabile dell'ora nota è migliore dell'uso dell'HPET da solo.

Utilizzare GetTickCount e aggiungere un altro contatore quando si uniscono i file di registro. Non ti darà una sequenza perfetta tra i diversi file di registro, ma almeno manterrà tutti i registri di ciascun file nell'ordine corretto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top