Réponse actualisée à une vieille question :
En C++11, vous pouvez obtenir de manière portative la plus haute résolution du timer avec :
#include <iostream>
#include <chrono>
#include "chrono_io"
int main()
{
typedef std::chrono::high_resolution_clock Clock;
auto t1 = Clock::now();
auto t2 = Clock::now();
std::cout << t2-t1 << '\n';
}
Exemple de sortie :
74 nanoseconds
"chrono_io" est une extension pour faciliter les problèmes d'E/S avec ces nouveaux types et est disponible gratuitement. aquí .
Il existe également une implémentation de <chrono>
disponible en boost (peut être encore sur tip-of-trunk, pas sûr qu'il ait été publié).
Mise à jour
Ceci est en réponse au commentaire de Ben ci-dessous, selon lequel les appels subséquents à std::chrono::high_resolution_clock
prennent plusieurs millisecondes dans le VS11. Vous trouverez ci-dessous une <chrono>
-compatible. Cependant, elle ne fonctionne que sur le matériel Intel, vous devez vous plonger dans l'assemblage en ligne (la syntaxe pour le faire varie selon le compilateur), et vous devez câbler la vitesse d'horloge de la machine dans l'horloge :
#include <chrono>
struct clock
{
typedef unsigned long long rep;
typedef std::ratio<1, 2800000000> period; // My machine is 2.8 GHz
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<clock> time_point;
static const bool is_steady = true;
static time_point now() noexcept
{
unsigned lo, hi;
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return time_point(duration(static_cast<rep>(hi) << 32 | lo));
}
private:
static
unsigned
get_clock_speed()
{
int mib[] = {CTL_HW, HW_CPU_FREQ};
const std::size_t namelen = sizeof(mib)/sizeof(mib[0]);
unsigned freq;
size_t freq_len = sizeof(freq);
if (sysctl(mib, namelen, &freq, &freq_len, nullptr, 0) != 0)
return 0;
return freq;
}
static
bool
check_invariants()
{
static_assert(1 == period::num, "period must be 1/freq");
assert(get_clock_speed() == period::den);
static_assert(std::is_same<rep, duration::rep>::value,
"rep and duration::rep must be the same type");
static_assert(std::is_same<period, duration::period>::value,
"period and duration::period must be the same type");
static_assert(std::is_same<duration, time_point::duration>::value,
"duration and time_point::duration must be the same type");
return true;
}
static const bool invariants;
};
const bool clock::invariants = clock::check_invariants();
Ce n'est donc pas portable. Mais si vous voulez expérimenter avec une horloge haute résolution sur votre propre matériel Intel, il n'y a rien de plus fin. Mais attention, les vitesses d'horloge actuelles peuvent changer dynamiquement (elles ne sont pas vraiment une constante de compilation). Et avec une machine multiprocesseur, vous pouvez même obtenir des horodatages de différents processeurs. Mais malgré tout, les expériences sur mon matériel fonctionnent assez bien. Si vous êtes coincé avec une résolution en millisecondes, cela pourrait être une solution de rechange.
Cette horloge a une durée en termes de vitesse d'horloge de votre processeur (comme vous l'avez indiqué). En d'autres termes, pour moi, cette horloge tique une fois tous les 1/2,800,000,000 de seconde. Si vous le souhaitez, vous pouvez convertir cette durée en nanosecondes (par exemple) avec :
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
auto t0 = clock::now();
auto t1 = clock::now();
nanoseconds ns = duration_cast<nanoseconds>(t1-t0);
La conversion tronquera les fractions d'un cycle du processeur pour former la nanoseconde. D'autres modes d'arrondi sont possibles, mais c'est un autre sujet.
Pour moi, cela donnera une durée aussi basse que 18 ticks d'horloge, ce qui correspond à 6 nanosecondes.
J'ai ajouté quelques "vérifications d'invariants" à l'horloge ci-dessus, dont la plus importante consiste à vérifier que la fonction clock::period
est correct pour la machine. Encore une fois, ce n'est pas un code portable, mais si vous utilisez cette horloge, vous vous êtes déjà engagé à le faire. Le code privé get_clock_speed()
montrée ici permet d'obtenir la fréquence maximale du processeur sous OS X, et cela devrait être le même nombre que le dénominateur constant de la fonction clock::period
.
Cet ajout vous permettra de gagner un peu de temps de débogage lorsque vous porterez ce code sur votre nouvelle machine et que vous oublierez de mettre à jour l'adresse de l'utilisateur. clock::period
à la vitesse de votre nouvelle machine. Toutes les vérifications sont effectuées soit au moment de la compilation, soit au moment du démarrage du programme. Il n'y aura donc pas d'impact sur les performances de clock::now()
le moins du monde.
4 votes
Soyez plus précis. Chronométrez-vous l'appel d'une fonction ou voulez-vous recevoir un signal après une période de temps donnée ? Il s'agit là de deux applications de chronométrage "simples", mais elles sont mises en œuvre de manière très différente. Notez l'utilisation du mot "simple" entre guillemets : le chronométrage dans les ordinateurs à usage général n'est jamais "simple".
0 votes
Version C stackoverflow.com/questions/361363/