La découverte de la fréquence d'horloge du PROCESSEUR (par cœur, par processeur)
Des programmes comme CPUz sont très bons à donner des informations en profondeur sur le système (vitesse de bus, les timings de la mémoire, etc.)
Cependant, est-il un moyen via un programme de calcul du par cœur (et par processeur, dans les systèmes multi-processeurs à plusieurs cœurs par PROCESSEUR) fréquence sans avoir à traiter avec un PROCESSEUR spécifique info.
Je suis en train de développer un anti triche outil (pour une utilisation avec de l'horloge limitée de l'indice de référence des compétitions) qui sera capable d'enregistrer de l'horloge du PROCESSEUR lors de l'indice de référence exécuter pour tous les cœurs actifs dans le système (sur tous les processeurs.)
- J'ai essayé de faire quelque chose comme cela auparavant - comme je suis l'auteur de l'une de ces overclocker repères. C'est très dur. Vous ne pouvez pas il suffit de mesurer la fréquence, vous avez également à rendre le système des minuteries résistant à l'horloge de la manipulation...
- Pour ajouter à mon point de vue. Des méthodes pour mesurer la fréquence d'impliquer le matériel/les compteurs de performance. Mais vous avez besoin d'une mesure précise du temps-la durée (comme le nombre de cycles en 1 seconde). Toutefois, lorsque vous avez affaire à un déterminé les tricheurs, vous ne pouvez pas avoir confiance dans les résultats de l'une de ces fonctions:
clock()
,gettimeofday()
,QueryPerformanceCounter()
, etc... comme ils peuvent tous être altéré. (Et je sais comment les manipuler moi-même...) - Wow... c'est révélateur... avez-vous finalement décider d'une stratégie pour au moins faire en sorte qu'il est difficile pour quelqu'un de tricher "facilement"?
- J'ai développé ce sujet dans la réponse que je viens de poster.
- Vous cet être marqués avec un PROCESSEUR de la famille?
- J'ai besoin de gérer les différentes CPU familles. Core 2/i7/i5/K8/K10/Bulldozer, etc. D'où le générique de la balise.
- Question connexe: stackoverflow.com/questions/65095/...
- Oui, c'est possible. Sur les Processeurs Intel, vous devez utiliser un kernel-mode driver WDM pour le faire. Le code Source et un exemple pour les puces Intel peut être trouvé sur mon blog: dima.de/blog/?p=101
Vous devez vous connecter pour publier un commentaire.
Je vais élargir mes commentaires ici. C'est trop gros et en profondeur, pour moi, pour s'adapter dans les commentaires.
Ce que vous essayez de faire est très difficile, au point d'être impossible pour les raisons suivantes:
rdtsc
ne PAS toujours donner la bonne fréquence à cause d'effets tels que le SpeedStep et le Turbo Boost.Il n'y a pas de portable de façon à obtenir la fréquence du processeur:
"Facile" à obtenir la fréquence du PROCESSEUR est d'appeler
rdtsc
deux fois avec un temps fixe de durée entre les deux. Puis en divisant la différence va vous donner la fréquence.Le problème est que
rdtsc
ne donne pas la fréquence réelle du processeur. Parce que les applications en temps réel telles que les jeux compter sur elle,rdtsc
doit être cohérente par le biais de la limitation des processeurs et de la technologie Turbo Boost. Donc, une fois que votre système démarre,rdtsc
sera toujours courir à la même vitesse (sauf si vous commencez à jouer avec les vitesses de bus avec SetFSB ou quelque chose).Par exemple, sur mon Core i7 2600K,
rdtsc
sera toujours montrer la fréquence à3.4 GHz
. Mais en réalité, il tourne au ralenti à1.6 GHz
et horloges jusqu'à4.6 GHz
en charge par l'overclocké Turbo Boost multiplicateur à46x
.Mais une fois que vous trouver un moyen pour mesurer la fréquence réelle, (ou que vous êtes assez heureux avec
rdtsc
), vous pouvez facilement obtenir la fréquence de chaque noyau à l'aide de fil-affinités.L'obtention de la Fréquence réelle:
Afin d'obtenir la valeur de la fréquence du processeur, vous avez besoin d'avoir accès à la Msr (certains modèles de registres) ou le matériel, les compteurs de performance.
Ce sont au niveau du noyau des instructions et nécessitent donc l'utilisation d'un pilote. Si vous tentez cela, dans Windows à des fins de distribution, vous aurez donc besoin de passer par le bon pilote de protocole de signature. En outre, le code ne diffèrent que par le processeur de la marque et le modèle de sorte que vous aurez besoin de différents codes de détection pour chaque génération de processeurs.
Une fois que vous arrivez à cette étape, il existe une variété de façons de lire la fréquence.
Sur des processeurs Intel, les compteurs de matériel laissez-vous compter brut de cycles CPU. Combiné avec une méthode précise de mesure en temps réel (section suivante), vous pouvez calculer la fréquence réelle. MSRs vous donner accès à d'autres informations telles que la fréquence du PROCESSEUR multiplicateur.
Toutes les méthodes connues pour mesurer la fréquence nécessite une mesure précise du temps:
C'est peut-être le plus gros problème. Vous avez besoin d'une minuterie pour être capable de mesurer la fréquence. Un hacker va être en mesure de toucher à toutes les horloges que vous pouvez utiliser en C/C++.
Cela comprend tous les éléments suivants:
clock()
gettimeofday()
QueryPerformanceCounter()
La liste va sur et sur. En d'autres termes, vous ne pouvez pas faire confiance à aucun des minuteries comme capable de pirate sera en mesure d'usurper l'identité de tous. Par exemple
clock()
etgettimeofday()
peut être dupé par la modification de l'horloge système directement dans l'OS. TromperQueryPerformanceCounter()
est plus difficile.L'obtention d'un Véritable Mesure du Temps:
Toutes les horloges énumérés ci-dessus sont vulnérables parce qu'ils sont souvent dérivées de la même base système de l'horloge, d'une certaine façon ou d'une autre. Et que le système de base de l'horloge est souvent liée à la base du système de l'horloge - qui peut être modifié après que le système a déjà démarré par le biais de l'overclocking utilitaires.
De sorte que la seule façon d'obtenir un système fiable et infalsifiable de la mesure du temps est de lire les horloges externes tels que la HPET ou la ACPI. Malheureusement, ceux-ci ne semblent exiger au niveau du noyau d'accès.
Pour Résumer:
Construction de n'importe quel genre de inviolables de référence sera presque certainement besoin d'écrire un pilote en mode noyau qui nécessite de signature de certificat pour Windows. C'est souvent un fardeau trop lourd pour les occasionnels de référence des écrivains.
Cela a entraîné une pénurie de trifouiller-preuve de repères qui a probablement contribué à la baisse générale de la compétitivité de l'overclocking de la communauté au cours des dernières années.
Je me rends compte de ce qui a déjà été répondu. Je le reconnais c'est fondamentalement un art noir, donc veuillez prendre ou à laisser, ou offrir de la rétroaction.
Dans une quête pour trouver la fréquence d'horloge sur étranglé (merci microsoft,hp et dell) HyperV hôtes (peu fiable perf compteur), et HyperV les invités (qui ne peut obtenir le stock de la vitesse de CPU, pas de courant), j'ai réussi, par essai erreur et fluke, pour créer une boucle qui boucle exactement une fois par cycle d'horloge.
Code comme suit - C# 5.0, SharpDev, 32bit, la Cible 3.5, Optimiser (essentiel), pas de debuger active (essentiel)
Notes
J'ai déjà posté sur ce sujet (avec un algorithme de base): ici. À ma connaissance, l'algorithme (voir la discussion) est très précis. Par exemple, Windows 7 rapports mon CPU horloge (2,00 GHz, CPU-Z comme 1994-1996 MHz et mon algorithme 1995025-1995075 kHz.
L'algorithme effectue un lot de boucles à faire ce qui provoque la fréquence du PROCESSEUR pour augmenter au maximum (comme il le sera également au cours de repères) donc, la vitesse d'accélération du logiciel n'entrera pas en jeu.
Informations supplémentaires ici et ici.
Sur la question de la vitesse d'accélération, je n'ai vraiment pas le voir comme un problème, sauf si une application utilise les valeurs de vitesse pour déterminer le temps écoulé et le temps eux-mêmes sont extrêmement importants. Par exemple, si une division de x cycles d'horloge pour terminer, il n'a pas d'importance si le CPU est cadencé à 3 GHz ou 300 MHz: il aura toujours besoin de x cycles d'horloge et la seule différence est qu'il va terminer la division en un dixième du temps à @ 3 GHz.
L'une des façons les plus simples de le faire est d'utiliser
RDTSC
, mais vu que c'est pour l'anti-triche mécanismes, je l'avais mis cela en tant que pilote du noyau ou d'un hyper-visière résident morceau de code.Vous auriez probablement aussi besoin de rouler votre propre code de timing**, ce qui peut être fait avec
RDTSC
(QPC utilisé dans l'exemple ci-dessous utiliseRDTSC
, et sa en fait très simple à désosser et utiliser une copie locale de la, ce qui signifie pour la modifier, vous auriez besoin de modifier votre pilote).** I ce serait pour la sécurité comme @Mystique mentionné, mais comme je n'ai jamais ressenti l'envie de renverser système de bas niveau des mécanismes de synchronisation, il peut être plus impliqués, ce serait bien si Mystique pourrait ajouter quelque chose sur ça 🙂
__rtdsc
intrinsèque 😛QueryPerformanceCounter()
a été HPET-basé sur le noyau multiprocesseur pour un long temps, parce que TSC n'est pas synchronisé sur les processeurs ou cœurs. Mais le principal problème que je faisais référence dans votre code (1) le occupé-attendre (2) n'utilisant pas de réel temps écoulé.Vous devez utiliser CallNtPowerInformation. Voici un exemple de code de putil projet.
Avec cela, vous pouvez obtenir en cours et max de la fréquence du PROCESSEUR. Autant que je sache, il n'est pas possible d'obtenir par la fréquence du PROCESSEUR.
On devrait se référer à ce livre blanc: La technologie Intel® Turbo Boost, Technologie Intel® Core™ Microarchitecture (Nehalem) sur les Processeurs. Fondamentalement, produire plusieurs lectures de l'UCC fixe compteur de performance sur une période d'échantillonnage T.
En commençant par l'architecture Nehalem, UCC d'augmenter et de diminuer le nombre de cliquez sur les tiques relativement à la Unhalted état de la base.
Quand SpeedStep ou Turbo Boost est activé, l'estimation de la fréquence à l'aide de l'UCC sera mesuré en conséquence; tandis que TSC reste constante. Par exemple, Turbo Boost dans l'action révèle que Delta(UCC) est supérieure ou égale à Delta(TSC)
Exemple en fonction
Core_Cycle
fonction à Cyring | CoreFreq GitHub.