VC++ utilizza una sintassi completamente diversa per l'assembly inline, ma solo nelle versioni a 32 bit. Il compilatore a 64 bit non supporta affatto l'assembly inline.
In questo caso, probabilmente lo è anche - rdtsc
ha (almeno) due problemi principali quando si tratta di sequenze di codice di temporizzazione. Innanzitutto (come la maggior parte delle istruzioni) può essere eseguito fuori ordine, quindi se stai provando a cronometrare una breve sequenza di codice, lo rdtsc
prima e dopo quel codice potrebbero essere entrambi eseguiti prima di esso, o entrambi dopo di esso, o cosa hanno tu (sono abbastanza sicuro che i due saranno sempre eseguiti in ordine l'uno rispetto all'altro, quindi almeno la differenza non sarà mai negativa).
In secondo luogo, su un sistema multi-core (o multiprocessore), un rdtsc può essere eseguito su un core/processore e l'altro su un core/processore diverso. In tal caso, un risultato negativo è interamente possibile.
In generale, se si desidera un timer preciso in Windows, sarà meglio utilizzare QueryPerformanceCounter
.
Se si vuole davvero utilizzare rdtsc
, credo che lo si dovrà fare in un modulo separato scritto interamente in linguaggio assembly (o utilizzare un compilatore intrinseco), quindi collegato con il C o C++. Non ho mai scritto che il codice per la modalità a 64 bit, ma in modalità a 32 bit è simile a questa:
xor eax, eax
cpuid
xor eax, eax
cpuid
xor eax, eax
cpuid
rdtsc
; save eax, edx
; code you're going to time goes here
xor eax, eax
cpuid
rdtsc
So che sembra strano, ma in realtà è giusto. Esegui CPUID perché è un'istruzione serializzante (non può essere eseguita fuori servizio) ed è disponibile in modalità utente.Lo si esegue tre volte prima di iniziare il cronometraggio perché Intel documenta il fatto che la prima esecuzione può/verrà eseguita a una velocità diversa dalla seconda (e ciò che raccomandano è tre, quindi tre è).
Quindi si esegue il codice sotto test, un'altra cpuid per forzare la serializzazione e l'ultimo rdtsc per ottenere il tempo dopo il completamento del codice.
Insieme a ciò, si desidera utilizzare qualsiasi mezzo che il sistema operativo fornisce per forzare il tutto su un unico processo/core. Nella maggior parte dei casi, si desidera forzare l'allineamento del codice: le modifiche nell'allineamento possono portare a differenze abbastanza sostanziali in termini di spee di esecuzione.
Infine, si desidera eseguirlo un numero di volte - ed è sempre possibile che venga interrotto nel mezzo di alcune cose (ad esempio un interruttore di attività), quindi è necessario essere preparati per la possibilità di un'esecuzione prendendo un po 'più a lungo del resto - ad esempio, 5 piste che richiedono ~ 40-43 cicli di clock a testa, e un sesto che richiede più di 100 cicli di clock. Chiaramente, in quest'ultimo caso, butti fuori l'outlier - non è dal tuo codice.
Riepilogo: la gestione dell'esecuzione dell'istruzione rdtsc è (quasi) l'ultima delle tue preoccupazioni. C'è ancora un po 'di tempo che lo ha bisogno di fare prima di poter ottenere risultati da rdtsc
che in realtà significheranno qualsiasi cosa.
"C++ è un sottoinsieme di C" - intendevi il contrario? – Mysticial
@Mysticial yup:) - modificato – user997112
Visual Studio non supporta l'assembly su x86-64. –