{"id":21651869,"url":"https://github.com/hoytech/timer-cpu","last_synced_at":"2026-07-29T08:31:42.880Z","repository":{"id":7032118,"uuid":"8306749","full_name":"hoytech/Timer-CPU","owner":"hoytech","description":"Precise user-space timer using the CPU clock","archived":false,"fork":false,"pushed_at":"2014-02-15T06:34:01.000Z","size":152,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-25T05:43:09.551Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoytech.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-20T05:26:43.000Z","updated_at":"2014-09-09T08:29:52.000Z","dependencies_parsed_at":"2022-09-07T15:51:00.523Z","dependency_job_id":null,"html_url":"https://github.com/hoytech/Timer-CPU","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FTimer-CPU","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FTimer-CPU/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FTimer-CPU/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FTimer-CPU/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoytech","download_url":"https://codeload.github.com/hoytech/Timer-CPU/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244547606,"owners_count":20470103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T07:49:55.236Z","updated_at":"2025-10-12T21:51:57.248Z","avatar_url":"https://github.com/hoytech.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"=head1 NAME\n\nTimer::CPU - Precise user-space timer using the CPU clock\n\n=head1 SYNOPSIS\n\n    use Timer::CPU;\n\n    my $elapsed_ticks = Timer::CPU::measure(sub {\n      ## Do stuff\n    });\n\n\n=head1 DESCRIPTION\n\nFor most timer operations, L\u003cTime::HiRes\u003e is great. Since it provides microsecond resolution in real \"wall-clock\" time it is very useful for determining how long an operation actually takes in seconds.\n\nHowever, on most CPUs it is possible to take much higher resolution measurements. These measurements aren't in absolute units like seconds but instead in \"cycles\" or \"ticks\". These measurements relate to wall-clock time via an unspecified conversion ratio and can therefore only be used for relative comparisons between code on the same machine (and are subject to other constraints described below).\n\nThe resolution of this module is extremely high. For example, it can detect the difference between a sub that returns nothing, one that returns a number, and one that returns an empty string. It can detect whether an C\u003cif\u003e branch is taken or not, and even the difference between C\u003ceq\u003e comparing strings that match and strings that differ by only the last character.\n\n\n=head1 USAGE\n\nThis module provides one function: C\u003cTimer::CPU::measure\u003e. Its first argument should be a callback code-ref. This is the code to be benchmarked. It is always called in void context. The return value is a number that corresponds to how many CPU cycles were spent executing your callback.\n\nThe following other arguments can be passed in as keyword arguments: C\u003cwarm_ups\u003e, C\u003citerations\u003e, and C\u003cmethod\u003e. For example:\n\n    say Timer::CPU::measure(sub { },\n                            warm_ups =\u003e 10,\n                            iterations =\u003e 50000,\n                            method =\u003e 'median');\n\nC\u003cmeasure\u003e will first invoke your provided callback C\u003cwarm_ups\u003e times (default is 2) and throw away the timing results. It will then invoke your callback C\u003citerations\u003e times (default is 1000), recording the number of ticks elapsed for each invocation. Finally, it will return a summary of the results according to the C\u003cmethod\u003e parameter which should be one of C\u003cmin\u003e, C\u003cmax\u003e, C\u003cmean\u003e, or C\u003cmedian\u003e. The default method is C\u003cmin\u003e.\n\n\n\n=head1 CAVEATS\n\nThere are many caveats to this timing technique, but there are caveats to all timing techniques.\n\nIt can be difficult to measure perl code by ticks elapsed because, compared to C, perl code typically does a lot \"under the hood\".\n\nOn x86 and x86-64, this module uses the C\u003crdtsc\u003e (\"ReaD Time-Stamp Counter\") instruction. On SPARC it accesses the C\u003c%tick\u003e register which is a 64-bit counter incremented every cycle. Various other CPUs might work (see C\u003ccycle.h\u003e) although they haven't been tested. An architecture that is noticeably missing is ARM.\n\nAs mentioned above, the real \"wall-clock\" time duration of a tick isn't necessarily known. You may be able to figure out the clock frequency with L\u003cSys::Info::Device::CPU\u003e, but (on x86/x86-64) you should first verify your CPU is modernish and has a constant time-stamp counter (look for \"constant_tsc\" in /proc/cpuinfo if you are on linux).\n\nIf your kernel context-switches out your process your timing data will be corrupted. While performing benchmarks you should consider running in single-user mode or, if you have multiple CPUs/cores, pegging your process to a particular CPU (with something like L\u003cSys::CpuAffinity\u003e).\n\nMany CPUs have the ability to dynamically scale their clock speed in order to save power. If the CPU your process is running on changes clock speed during your measurements your data will be corrupted. You should consider fixing your CPU to a constant clock speed while running benchmarks.\n\nIf the machine is hibernated or suspended, data will be corrupted also.\n\nOn some architectures, operating systems can disable access to the time-stamp counter (ie by setting a bit in the CR4 register on x86). This is uncommon but is sometimes done in virtualised environments to protect against harvesting information from timing side-channels.\n\n\n\n\n\n\n=head1 SEE ALSO\n\nL\u003cTimer-CPU github repo|https://github.com/hoytech/Timer-CPU\u003e\n\nL\u003cTime::HiRes\u003e\n\nL\u003cTime-Stamp Counter|http://en.wikipedia.org/wiki/Time_Stamp_Counter\u003e\n\nL\u003cString::Compare::ConstantTime\u003e\n\n\n\n=head1 AUTHOR\n\nDoug Hoyte, C\u003c\u003c \u003cdoug@hcsw.org\u003e \u003e\u003e\n\nThe tick collection routines are copied from the file C\u003ccycle.h\u003e in the FFTW 3 project. They are written by Matteo Frigo and contributors (see source code) and are distributed under the MIT license.\n\n\n=head1 COPYRIGHT \u0026 LICENSE\n\nCopyright 2013-2014 Doug Hoyte.\n\nThis module is licensed under the same terms as perl itself.\n\n\n=cut\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Ftimer-cpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoytech%2Ftimer-cpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Ftimer-cpu/lists"}