Rdtsc
Versiunea actuală a paginii nu a fost încă revizuită de colaboratori experimentați și poate diferi semnificativ de
versiunea revizuită pe 29 decembrie 2019; verificările necesită
5 modificări .
rdtsc ( Read Time Stamp Counter ) este o instrucțiune de asamblare pentru platformele x86 și x86_64 care citește contorul TSC ( Time Stamp Counter ) și returnează numărul de 64 de biți de cicluri de ceas în registrele EDX: EAX de la ultima resetare a procesorului .
rdtsc este acceptat pe procesoare Pentium (și compatibile) și mai noi. Opcode : 0F 31 [1] .
rdtscp [2] a fost acceptat de la Intel Nehalem și AMD Family 0x0F [3] . Opcode: 0F 01 F9 [4] .
Utilizare
rdtsc este cel mai frecvent utilizat:
- a măsura timpul;
- pentru măsurarea precisă a intervalelor de timp, inclusiv în timpul optimizării (măsurarea timpului necesar executării instrucțiunilor specifice sau setării acestora);
- în scopuri anti-depanare; [5] [6]
- ca sursă de entropie pentru generatoarele de numere pseudoaleatoare . [7]
Beneficii
În comparație cu API-urile furnizate de sistemul de operare precum WINAPI::QueryPerformanceCounter() sau gettimeofday() instrucțiunile rdtsc/rdtscp pot oferi următoarele avantaje:
- Precizie mai bună, în special pentru arhitecturi și sisteme de operare vechi care nu au suport complet HPET . Astfel de sisteme de operare folosesc un temporizator de sistem cu o precizie redusă (uneori până la o porțiune de planificare, OsTimeSlice, de ordinul unităților sau zecilor de milisecunde).
- Mai puțină suprasarcină: instrucțiunile rdtsc/rdtscp se execută în aproximativ o duzină de cicluri de ceas, ceea ce este mult mai rapid decât apelurile de sistem.
- Nu necesită trecerea la modul privilegiat Ring0 sau hypervisor pe majoritatea sistemelor (dacă comanda este permisă pe sistemul de operare).
Probleme de utilizare
- Ar trebui să existe moduri de program care nu necesită această comandă, deoarece RDTSC / RDTSCP poate fi indisponibil sau interzis pentru utilizare pe sistemul final în care va fi utilizată aplicația:
- pe procesoare foarte vechi (de exemplu, 80486 ) sau pe sisteme care nu implementează pe deplin arhitectura x86.
- instrucțiunea poate fi potențial transformată într-o instrucțiune privilegiată (al 3-lea bit din registrul de control CR4 este setat de sistemul de operare), iar utilizarea sa va duce la aruncarea unei excepții în program.
- instrucțiunea poate fi interceptată de sistemele de virtualizare, utilizarea ei va duce la un hypercall.
- Modul de economisire a energiei poate afecta numărul de ceas:
- Când frecvența este modificată dinamic de procesor (reducerea și creșterea frecvenței în SpeedStep, Turbo Boost, Cool&Quiet și tehnologii similare), viteza contorului TSC se modifică.
- Punerea unui procesor în modul de repaus profund C3 oprește contorul TSC pe procesoarele mai vechi.
- În procesoarele Intel moderne ( Nehalem și mai noi) și AMD (probabil de la K10 Barcelona/Phenom), contorul TSC este independent de utilizarea tehnologiilor de economisire a energiei și crește la o frecvență constantă, indiferent de frecvența la care rulează procesorul și dacă rula sau era în stare de somn. Un astfel de contor se numește invariant ( invariant TSC ).
- Este posibil ca măsurătorile precise să nu fie posibile cu o singură execuție a fragmentului măsurat de instrucțiuni din cauza influenței cache-urilor procesorului la accesarea memoriei. În mod tradițional, se rezolvă prin măsurarea repetată a unui fragment de program sau prin repetarea fragmentului măsurat într-o buclă.
- RDTSC poate fi reordonat cu instrucțiuni măsurate pe procesoarele în afara comenzii. Reordonarea poate fi dezactivată prin adăugarea de comenzi de serializare (de ex. CLD/CLC pentru modelele Pentium P5, P54 [8] sau cpuid pentru modelele mai noi) sau utilizând RDTSCP.
- Măsurătorile de scurtă durată a fragmentelor pot fi instabile în sistemele cu mai multe nuclee și multi-procesor sau când se utilizează HyperThreading din cauza influenței reciproce a altor fire și a încărcării pe unitățile de procesor partajate.
- Contoarele TSC pot, în cazuri rare, să nu fie sincronizate pe unele sisteme multi-core sau multi-procesor, în special:
- La inițializarea procesoarelor.
- Este posibil ca contoarele să devină desincronizate pe sistemele multi-core timpurii din cauza inițializării incorecte a procesoarelor de către unele BIOS-uri. Remediat prin actualizarea BIOS-ului sau actualizarea sistemului de operare. Există programe pentru a verifica această eroare. [9]
- Sistemul de operare poate comuta firul între diferite nuclee care au contoare nesincronizate. La nivel de aplicație, puteți urmări schimbarea nucleului pe sisteme multi-core folosind instrucțiunea RDTSCP, care, funcționând similar cu RDTSC, returnează suplimentar numărul procesorului logic în registrul ECX.
Pentru a rezolva multe probleme, se recomandă fixarea firului de execuție pe un anumit procesor ( afinitate CPU ) și dezactivarea tehnologiilor de schimbare automată a frecvenței (tehnologii de economisire a energiei și modificări dinamice de performanță).
Note
- ↑ Manual pentru dezvoltatori de software pentru arhitecturi Intel® 64 și IA-32 . — Vol. 2 (Referință setului de instrucțiuni). - P. 4-301.
- ↑ O versiune de serializare a instrucțiunii rdtsc, care citește și IA32_TSC_AUX MSR, care stochează adesea numărul nucleului.
- ↑ rdtscp . Consultat la 1 noiembrie 2011. Arhivat din original pe 2 ianuarie 2012. (nedefinit)
- ↑ Manual pentru dezvoltatori de software pentru arhitecturi Intel® 64 și IA-32 . — Vol. 2 (Referință setului de instrucțiuni). - P. 4-303.
- ↑ Referință Windows Anti-Debug | Comunitatea Symantec Connect . Data accesului: 30 decembrie 2011. Arhivat din original la 14 ianuarie 2012. (nedefinit)
- ↑ Slide 58 Anti-Debugging bazat pe sincronizare Arhivat 4 martie 2012.
- ↑ Tom St. Denis, Simon Johnson, Criptografie pentru dezvoltatori Arhivat la 9 octombrie 2021 la Wayback Machine .
- ↑ Cum se optimizează pentru familia de microprocesoare Pentium Arhivat 6 ianuarie 2012 la Wayback Machine // 1996-2000 de Agner Fog. Capitolul „30. Viteza de testare”, arhivată 19 noiembrie 2011.
- ↑ Afinitatea ICE . Consultat la 19 octombrie 2011. Arhivat din original pe 7 septembrie 2011. (nedefinit)
Link -uri