8
votes

RDTSC, trop de cycles

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 15
model       : 4
model name  : Intel(R) Xeon(TM) CPU 3.00GHz
stepping    : 3
cpu MHz     : 3000.105
cache size  : 2048 KB
fdiv_bug    : no
hlt_bug     : no
f00f_bug    : no
coma_bug    : no
fpu     : yes
fpu_exception   : yes
cpuid level : 5
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss constant_tsc up pebs bts pni
bogomips    : 6036.62
clflush size    : 64

9 commentaires

Cela implique beaucoup que vous ne pouvez pas compter. Utilisez beaucoup à la place.


RDTSC Écrit sur% EDX:% EAX`. Votre fonction Tick () est fausse.


avec la deuxième fonction la même sortie


Bien sûr, en utilisant = A retournera 32 bits inférieurs sur X86_64 et les 32 bits inférieurs sont suffisants pour ce test de toute façon


Assurez-vous de comprendre pourquoi rdtsc n'est pas une minuterie fiable.


@Thanatos: Vous pouvez sûrement aider l'op sur la raison pour laquelle vous dites cela.


Quand je gère votre code, j'ai presque toujours 42. Douglas Adams serait heureux. :-)


Quel système d'exploitation utilisez-vous pour ce test (Distro et version du noyau)?


Version Linux 2.6.26-2-686 (Debian 2.6.26-26Lenny1) (Dannf@debian.org) (Version GCC 4.1.3 20080704 (PRERRELASE) (Debian 4.1.2-25)) # 1 SMP Thu 25 nov. 01 : 53: 57 UTC 2010


5 Réponses :


7
votes

Il y a un nombre quelconque de raisons pour obtenir un grand nombre:

  • Le système d'exploitation a fait un changement de contexte et votre processus a été mis en veille.
  • Une recherche de disque s'est produite et votre processus a été mis endormi.
  • ... n'importe laquelle des raisons de raisons sur la raison pour laquelle votre processus pourrait être ignoré.

    Notez que RDTSC n'est pas particulièrement fiable pour la synchronisation sans travail, car:

    • Les vitesses de processeur peuvent changer et ainsi, la longueur d'un cycle (lorsqu'elle est mesurée en secondes) change.
    • Différents processeurs peuvent avoir des valeurs différentes pour le TSC pour un instant donné à temps.

      La plupart des systèmes d'exploitation ont une horloge de haute précision ou une méthode de synchronisation. clock_gettime sous Linux par exemple, en particulier les horloges monotoniques. (Comprenez aussi la différence entre une horloge murale et une horloge monotonique: une horloge murale peut se déplacer vers l'arrière - même en UTC.) Sous Windows, je pense que la recommandation est QueryHighperformancecounter . Typiquement, ces horloges fournissent plus que suffisamment de précision pour la plupart des besoins.


      Aussi, en regardant l'assemblée, on dirait que vous obtenez seulement 32 bits de la réponse: je ne vois pas % edx être enregistré après rdtsc .


      exécutant votre code, je reçois des timings de 120-150 ns pour clock_gettime à l'aide de clock_montonique et 70-90 cycles pour RDTSC (~ 20 NS à pleine vitesse, mais Je soupçonne que le processeur est en panne, et c'est vraiment environ 50 NS). (Sur une ordinateur portable Desktop (Darn Ssh, oublié quelle machine j'étais sur!) C'est à peu près une utilisation constante de 20% de la CPU), assurez-vous que votre machine n'est pas enlisée?


8 commentaires

structure TimesPec TS1, TS2; horloge_gettime (clock_mononic, & ts1); clock_gettime (horloge_mononic, & ts2); TS2.TV_NSEC-TS1.TV_NSEC ~ 8000 Il est trop grand.


= A copie des valeurs à partir d'EDX et de EAX.


@Mifki: Si vous le dites: peut-être que l'OP est mal compilé. Voyez-vous % edx être enregistré dans l'assembly?


@Thanatos à nouveau: Si compilé pour 32 bits, = A Copiera EAX et EDX sur un emplacement spécifié.


@exxxxxxxxxxxx: Je reçois DIFFS dans la gamme ~ 130, sur un noyau Intel i7.


@Mifki: Lire L'assemblage que l'OP a affiché. Auparavant, il n'avait rien inclus utilisé en utilisant % edx .


@Thanatos difficilement à raconter maintenant, peut-être juste un mauvais code collé. = Un assemblage correct produit avec les deux registres


En fait, sur un kernel de kernel moderne horloge_gettime est exécuté dans un espace utilisateur (c'est un VDSO plutôt qu'un système système approprié), il est donc très efficace. La principale raison pour laquelle la RDTSC plaine est plus rapide, c'est qu'il n'inclut pas les barrières nécessaires pour empêcher le processeur de hisser la RDTSC avant les instructions que l'on essaie de temps.



0
votes

Juste une idée - peut-être que ces deux instructions RDTSC sont exécutées sur différents cœurs? Les valeurs RDTSC peuvent varier légèrement à travers les noyaux.


1 commentaires

Seulement noyau, juger par / sys / dispositifs / système / CPU /



4
votes

Cela ressemble à votre système d'exploitation désactivé l'exécution de RDTSC dans l'espace utilisateur. Et votre application doit passer au noyau et à dos, ce qui prend beaucoup de cycles.

Ceci est du manuel du développeur de logiciels Intel:

En mode protégé ou virtuel 8086, l'horodatage désactiver (TSD) drapeau dans Enregistrement CR4 restreint l'utilisation de l'instruction RDTSC comme suit. Quand le drapeau TSD est claire, l'instruction RDTSC peut être exécutée à tout niveau de privilège; Quand le drapeau est défini, l'instruction ne peut être exécutée qu'au niveau de privilège 0. (lors de l'adresse réelle Mode, l'instruction RDTSC est toujours activée.)

EDIT:

Répondre à la commentaires d'Aix, j'explique pourquoi TSD est probablement la raison ici.

Je ne connais que ces possibilités pour un programme d'exécution d'une seule instruction plus longue que d'habitude:

  1. courir sous certains émulateurs,
  2. Utilisation de code auto-modifié,
  3. Interrupteur de contexte,
  4. Interrupteur du noyau.

    Les 2 premières raisons ne peuvent généralement pas retarder l'exécution pendant plus de quelques centaines de cycles. Les cycles de 2000-2500 sont plus typiques du commutateur contextuel / noyau. Mais il est pratiquement impossible d'attraper un changement de contexte plusieurs fois au même endroit. Donc, il devrait être un commutateur de noyau. Ce qui signifie que l'un ou l'autre programme est exécuté sous le débogueur ou le RDTSC n'est pas autorisé en mode utilisateur.

    La raison la plus probable du système d'exploitation de désactiver RDTSC peut être une sécurité. Il y avait des tentatives d'utilisation de RDTSC pour casser des programmes de cryptage.


15 commentaires

Je n'ai pas voté sur la réponse de toute façon, mais je pense que cela serait amélioré si vous avez déclaré pourquoi Vous avez pensé que TSD pourrait être le coupable.


@aix je l'ai expliqué. Merci.


@Eveny Kluev et pour Clock_GetTime Explications similaires? J'ai eu 8000 NSEC avec l'utilisation de clock_montonic id. C'est énorme = /


@exxxxxxxxxxxx clock_getTime est probablement exécuté par le noyau, de sorte qu'au moins 2000 cycles est requis. Peut-être plus. Mais 8000 Nsec semble trop élevé - je ne peux pas l'expliquer.


@Evgeny Kluev i.e. Je ne peux pas en l'espoir de mesurer par exemple. intervalle de 100 cycles. Il existe probablement des moyens d'éviter ce problème?


@exxxxxxxxxxxx Il peut être lié à la résolution (précision) de Clock_GetTime, mais vous devez ensuite voir 8000 intervalles NSEC mélangés avec des intervalles de zéro.


@Evgeny Kluev Run Clock_GetTime ~ 50 fois les résultats sont de 8 000-11000 et 2 fois était de 2000 et 3000. C'est étrange. La CPU n'a pas été chargée


@exxxxxxxxxxxxx est probablement le seul moyen de mesurer les intervalles courts consiste à convaincre votre sysadmin d'autoriser RDTSC (car le système n'a qu'un noyau et donc il n'y a donc aucun risque de sécurité sur ce système).


@exxxxxXXXXXXX résolution affecte définitivement les résultats, je ne peux toujours pas expliquer pourquoi l'intervalle moyen est si élevé.


@EvgenyKluev Ne pensez-vous pas que le processus en mode utilisateur sera simplement tué s'il tente d'exécuter des instructions qu'il n'est pas autorisé?


@Mifki pas nécessaire. Dans ce système de cas particulier peut le réaliser en mode de noyau en toute sécurité. Le programme de pirate de pirate ne peut pas deviner ce qui se passe sur un autre fil d'hyperthreading s'il est donné une telle minuterie sans précédent.


@EvgenyKluev Selon ce programme de test inclus avec le noyau - MJMWired.net /kernel/documentation/prctl/disable-tsc-test.c (et définit pr_tsc_enable pr_tsc_sigsegv en pr.ctl.h) - Il y aura SIGSEGV.


@Mifki peut être que cela donne à SIGSEGV juste pour les tests et l'exécute en mode noyau dans la vie réelle ... Je ne sais pas. Ce serait raisonnable de ne pas trop que SIGSEGV dans le code de production. Sinon, de nombreuses applications utiles seront ... inutilisables :)


@Evenykluev Que voulez-vous dire ?? Le noyau est la même chose toujours, il ne peut pas tuer l'application dans un cas et ne pas dans une autre. Bien sûr, il est possible que ce programme et ce nom de définition soient obsolètes et que quelque chose changeait .. Malheureusement, je n'ai pas de boîte de Linux non virtualisée pour m'essayer, mais je vais essayer d'en trouver un.


@Mifki je ne connais pas les détails. Jamais essayé de fonctionnalités de sécurité. Je dis juste ce qui peut être un comportement possible. J'ai peut-être tort.



11
votes

J'ai essayé votre code sur plusieurs distributions Linux en cours d'exécution sur différents processeurs Intel (Certes tout plus récents que le Pentium 4 HT 630, vous semblez utiliser). Dans tous ces tests, j'ai obtenu des valeurs entre 25 et 50 cycles.

Ma seule hypothèse cohérente avec toutes les preuves est que vous exécutez votre système d'exploitation à l'intérieur d'une machine virtuelle plutôt que sur du métal nu et que TSC devient virtualisé.


0 commentaires

1
votes

Cache d'instructions Miss Miss? (Ceci est ma supposition)

Également, éventuellement,

Basculez vers l'hyperviseur dans un système virtualisé? Restes de programme Bootstrap (y compris l'activité de réseau sur la même processeur)?

à Thanatos: sur les systèmes plus récents que 2008, RDTSC () est une horloge murale et ne varie pas avec les étapes de fréquence. < P> Pouvez-vous essayer ce petit code? xxx


1 commentaires

Ce n'est pas une réponse techniquement, c'est plus d'engagement de suivi. Cependant, vous n'avez pas assez de représentant à commenter et on dirait que vous engagez activement l'OP (et semblez avoir la connaissance de répondre à cela), donc je ne supprime pas ce post. Si vous ne recevez pas de réponse de l'OP, veuillez transformer cela en une réponse qui suppose simplement ce que vous avez énoncé - ou cela sera probablement supprimé.