libcpucycles-20260901/0000755000000000000000000000000015245636444013153 5ustar rootrootlibcpucycles-20260901/Makefile0000644000000000000000000000015015245636444014607 0ustar rootrootdefault: cd build && $(MAKE) install: cd build && $(MAKE) install clean: cd build && $(MAKE) clean libcpucycles-20260901/autogen/0000755000000000000000000000000015245636444014615 5ustar rootrootlibcpucycles-20260901/autogen/api-version0000755000000000000000000000061515245636444017001 0ustar rootroot#!/usr/bin/env python3 import os import re def save(fn,x): if os.path.exists(fn): with open(fn) as f: cur = f.read() if cur == x: return with open(fn,'w') as f: f.write(x) with open('version') as f: version = f.read().strip() with open('doc/api.md') as f: x = f.read() x = re.sub(r'string: e\.g\., `"[0-9]*"`',f'string: e.g., `"{version}"`',x) save('doc/api.md',x) libcpucycles-20260901/autogen/html0000755000000000000000000000566415245636444015522 0ustar rootroot#!/usr/bin/env python3 import os import datetime import markdown def load(fn): with open(fn) as f: return f.read() style = load('autogen/html-style') sitetitle = load('autogen/html-title').strip() files = [] os.makedirs('doc/html',exist_ok=True) with open('autogen/html-files') as f: for line in f: line = line.strip() line = line.split(':') if len(line) != 3: continue files += [line] class superscripts(markdown.extensions.Extension): def extendMarkdown(self,md): md.inlinePatterns.register(markdown.inlinepatterns.SimpleTagInlineProcessor(r'()\^(.*?)\^','sup'),'sup',175) # this paragraph derived from python-markdown AUTOLINK_RE = r'<((?:[Ff]|[Hh][Tt])[Tt][Pp][Ss]?://[^<>]*)>' class ttautolinkprocessor(markdown.inlinepatterns.InlineProcessor): def handleMatch(self,m,data): tt = markdown.inlinepatterns.etree.Element('span') tt.set('class','url') tt.text = markdown.inlinepatterns.util.AtomicString(m.group(1)) e = markdown.inlinepatterns.etree.Element('a') e.set('href',self.unescape(m.group(1))) e.append(tt) return e,m.start(0),m.end(0) class ttautolink(markdown.extensions.Extension): def extendMarkdown(self,md): md.inlinePatterns.register(ttautolinkprocessor(AUTOLINK_RE,md),'autolink',119) for md,html,pagetitle in files: fnmd = 'doc/%s.md' % md fnhtml = 'doc/html/%s.html' % html output = '' x = load(fnmd) x = markdown.markdown(x,extensions=['markdown.extensions.extra','markdown.extensions.tables',superscripts(),ttautolink()]) mtime = datetime.datetime.fromtimestamp(os.path.getmtime(fnmd),datetime.UTC).strftime('%Y.%m.%d') output += '\n\n' output += style output += '\n' output += sitetitle output += ': ' output += pagetitle output += '\n' output += '\n' output += '\n' output += '\n' output += '
\n' output += '
'+sitetitle+': '+pagetitle+'
\n' output += x output += '
Version:\n' output += 'This is version %s of the "%s" web page.\n' % (mtime,pagetitle) output += '\n' output += '
\n' output += '\n' output += '\n' if not os.path.exists(fnhtml) or output != load(fnhtml): with open(fnhtml+'.new','w') as f: f.write(output) os.chmod(fnhtml+'.new',0o444) os.rename(fnhtml+'.new',fnhtml) libcpucycles-20260901/autogen/html-files0000644000000000000000000000027615245636444016611 0ustar rootrootreadme:index:Intro download:download:Download install:install:Install api:api:API counters:counters:Counters selection:selection:Selection security:security:Security license:license:License libcpucycles-20260901/autogen/html-style0000644000000000000000000000617715245636444016655 0ustar rootroot libcpucycles-20260901/autogen/html-title0000644000000000000000000000001515245636444016617 0ustar rootrootlibcpucycles libcpucycles-20260901/autogen/man0000755000000000000000000000060515245636444015317 0ustar rootroot#!/bin/sh pandoc --standalone --to man --metadata title=cpucycles --metadata section=3 < doc/api.md > doc/man/cpucycles.3 pandoc --standalone --to man --metadata title=cpucycles-info --metadata section=1 < doc/cpucycles-info.md > doc/man/cpucycles-info.1 pandoc --standalone --to man --metadata title=cpucycles-open --metadata section=1 < doc/cpucycles-open.md > doc/man/cpucycles-open.1 libcpucycles-20260901/autogen/readme-version0000755000000000000000000000066315245636444017470 0ustar rootroot#!/usr/bin/env python3 import os import re def save(fn,x): if os.path.exists(fn): with open(fn) as f: cur = f.read() if cur == x: return with open(fn,'w') as f: f.write(x) with open('version') as f: version = f.read().strip() with open('doc/readme.md') as f: x = f.read() x = re.sub(r'Latest release: \[[0-9]*\]\(download.html\)',f'Latest release: [{version}](download.html)',x) save('doc/readme.md',x) libcpucycles-20260901/autogen/wrapper-version0000755000000000000000000000061415245636444017707 0ustar rootroot#!/usr/bin/env python3 import os import re def save(fn,x): if os.path.exists(fn): with open(fn) as f: cur = f.read() if cur == x: return with open(fn,'w') as f: f.write(x) with open('version') as f: version = f.read().strip() with open('cpucycles/wrapper.c') as f: x = f.read() x = re.sub('return "[0-9]*";',f'return "{version}";',x) save('cpucycles/wrapper.c',x) libcpucycles-20260901/command/0000755000000000000000000000000015245636444014571 5ustar rootrootlibcpucycles-20260901/command/cpucycles-info.c0000644000000000000000000000425615245636444017667 0ustar rootroot#include #include #include #include #include #include #include #define TIMINGS 64 // must be multiple of 4 static long long t[TIMINGS+1]; static long long u[TIMINGS]; static void t_print(void) { long long iqm = 0; long long i,j; for (i = 0;i < TIMINGS;++i) u[i] = t[i] = t[i+1]-t[i]; for (i = 0;i < TIMINGS;++i) for (j = i+1;j < TIMINGS;++j) if (u[j] < u[i]) { long long z = u[i]; u[i] = u[j]; u[j] = z; } j = 0; for (i = TIMINGS/4;i < 3*TIMINGS/4;++i) { iqm += u[i]; // if this overflows then the numbers are garbage anyway j += 1; } iqm = (iqm+j/2)/j; // not worried about the marginal bias downwards printf("cpucycles iqm %lld ",iqm); for (i = 0;i < TIMINGS;++i) printf("%+lld",t[i]-iqm); printf("\n"); fflush(stdout); } static long long microseconds(void) { struct timeval t; long long result; gettimeofday(&t,(struct timezone *) 0); result = t.tv_sec; result *= 1000000; result += t.tv_usec; return result; } static volatile int v; static void measure_cpucycles(void) { long long loops,i,j; printf("cpucycles persecond %lld\n",cpucycles_persecond()); printf("cpucycles implementation %s\n",cpucycles_implementation()); for (i = 0;i <= TIMINGS;++i) t[i] = cpucycles(); t_print(); for (loops = 1024;loops <= 1048576;loops *= 2) { long long t00,t01,t10,t11; long long m0,m1; double ratiobelow,ratioabove; t00 = cpucycles(); m0 = microseconds(); t01 = cpucycles(); for (j = 0;j < loops;++j) v = 0; t10 = cpucycles(); m1 = microseconds(); t11 = cpucycles(); if (t01 < t00) continue; if (t10 < t01) continue; if (t11 < t10) continue; if (m1 <= m0+2) continue; ratiobelow = floor((1000000.0*(t10-t01))/(m1+1-m0)); ratioabove = ceil((1000000.0*(t11-t00))/(m1-m0-1)); printf("cpucycles observed persecond %.0lf...%.0lf with %lld loops %lld microseconds\n",ratiobelow,ratioabove,loops,m1-m0); } } int main(int argc,char **argv) { cpucycles_tracesetup(); printf("cpucycles version %s\n",cpucycles_version()); measure_cpucycles(); return 0; } libcpucycles-20260901/command/cpucycles-open.sh0000644000000000000000000000046115245636444020057 0ustar rootroot#!/bin/sh ( echo 1 /proc/sys/kernel/perf_user_access echo 2 /proc/sys/kernel/perf_event_paranoid echo 2 /sys/devices/cpu/rdpmc echo 2 /sys/devices/cpu_core/rdpmc echo 2 /sys/devices/cpu_atom/rdpmc echo 0 /proc/sys/kernel/nmi_watchdog ) | while read x fn do [ -e $fn ] && echo $x > $fn done libcpucycles-20260901/compilers/0000755000000000000000000000000015245636444015150 5ustar rootrootlibcpucycles-20260901/compilers/default0000644000000000000000000000016315245636444016517 0ustar rootrootgcc -Wall -fPIC -fwrapv -O -fvisibility=hidden clang -Wall -fPIC -fwrapv -Qunused-arguments -O -fvisibility=hidden libcpucycles-20260901/configure0000755000000000000000000002611115245636444015063 0ustar rootroot#!/usr/bin/env python3 import os import shutil import sys import platform import subprocess import tempfile prefix = '/usr/local' clean = True darwin = platform.system() == 'Darwin' def hostsanitize(host): host = host.split('-')[0] host = ''.join(c for c in host if c in '_0123456789abcdefghijklmnopqrstuvwxyz') for prefix,result in ( ('amd64','amd64'), ('x86_64','amd64'), ('x86','x86'), ('i386','x86'), ('i486','x86'), ('i586','x86'), ('i686','x86'), ('arm64','arm64'), ('armv8','arm64'), ('aarch64','arm64'), ('arm','arm32'), ('riscv64','riscv64'), ('riscv','riscv32'), ('loongarch64','loong64'), ('mips64','mips64'), ('mips','mips32'), ('ppc64','ppc64'), ('powerpc64','ppc64'), ('powerpc','ppc32'), ('ppc','ppc32'), ('sparc64','sparc64'), ('sparcv9','sparc64'), ('sun4u','sparc64'), ('sun4v','sparc64'), ('sparc','sparc32'), ('sun','sparc32'), ): if host.startswith(prefix): return result return host host = hostsanitize(platform.machine()) configurelog = '' def log(x): global configurelog configurelog += x+'\n' print(x) makefile = '' for arg in sys.argv[1:]: if arg.startswith('--prefix='): prefix = arg[9:] continue if arg.startswith('--host='): host = hostsanitize(arg[7:]) continue if arg == '--clean': clean = True continue if arg == '--no-clean': clean = False continue if arg == '--darwin': darwin = True continue if arg == '--no-darwin': darwin = False continue raise ValueError('unrecognized argument %s' % arg) echoargs = './configure' echoargs += ' --prefix=%s' % prefix echoargs += ' --host=%s' % host if clean: echoargs += ' --clean' if not clean: echoargs += ' --no-clean' if darwin: echoargs += ' --darwin' if not darwin: echoargs += ' --no-darwin' log(echoargs) if prefix[0] != '/': raise ValueError('prefix %s is not an absolute path' % prefix) rpath = None # XXX: rpath = '%s/lib' % prefix if clean: shutil.rmtree('build/%s' % host,ignore_errors=True) def dirlinksym(dir,source,target): with tempfile.TemporaryDirectory(dir=dir) as t: os.symlink(target,'%s/symlink' % t) os.rename('%s/symlink' % t,'%s/%s' % (dir,source)) os.makedirs('build/%s' % host,exist_ok=True) os.makedirs('build/%s/package/bin' % host,exist_ok=True) os.makedirs('build/%s/package/lib' % host,exist_ok=True) os.makedirs('build/%s/package/include' % host,exist_ok=True) if clean: os.symlink('../..','build/%s/src' % host) # ----- build scripts os.makedirs('build/%s/scripts'%host,exist_ok=True) dirlinksym('build/%s/scripts'%host,'install','../src/scripts-build/install') # ----- shared-library variations so = 'dylib' if darwin else 'so' so1 = '1.dylib' if darwin else 'so.1' soname = 'install_name' if darwin else 'soname' syslibs = '-lm' if darwin else '-lm -lrt' # ----- compilers def compilerversion(c): try: p = subprocess.Popen(c.split()+['--version'],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True) out,err = p.communicate() assert not err assert not p.returncode return out except: pass firstcompiler = None with open('compilers/default') as f: for c in f.readlines(): c = c.strip() cv = compilerversion(c) if cv == None: log('skipping default compiler %s' % c) continue log('using default compiler %s' % c) firstcompiler = c break if firstcompiler is None: raise ValueError('did not find a working compiler') with open('build/%s/scripts/compiledefault' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('dir="$1"; shift\n') f.write('base="$1"; shift\n') f.write('ext="$1"; shift\n') f.write('\n') f.write('cd "$dir" && \\\n') f.write('%s \\\n' % firstcompiler) f.write(' "$@" \\\n') f.write(' -c "$base.$ext"\n') os.chmod('build/%s/scripts/compiledefault' % host,0o755) # ----- libcpucycles os.makedirs('build/%s/cpucycles' % host,exist_ok=True) os.makedirs('build/%s/package/man/man1' % host,exist_ok=True) os.makedirs('build/%s/package/man/man3' % host,exist_ok=True) for fn in sorted(os.listdir('cpucycles')): if not fn.endswith('.h'): continue dirlinksym(f'build/{host}/cpucycles',fn,f'../src/cpucycles/{fn}') shutil.copy2('cpucycles/cpucycles.h','build/%s/package/include/cpucycles.h'%host) shutil.copy2('doc/man/cpucycles-info.1','build/%s/package/man/man1/cpucycles-info.1'%host) shutil.copy2('doc/man/cpucycles-open.1','build/%s/package/man/man1/cpucycles-open.1'%host) shutil.copy2('doc/man/cpucycles.3','build/%s/package/man/man3/cpucycles.3'%host) with open('build/%s/cpucycles/compile-ticks' % host,'w') as f: f.write('#!/bin/sh\n') f.write('arch="$1"; shift\n') f.write('x="$1"; shift\n') f.write('for source in try-"$arch"-"$x".c try-default-zero.c\n') f.write('do\n') f.write(' cp "$source" "$arch"-"$x".c\n') f.write(' %s \\\n' % firstcompiler) f.write(' -Dticks=cpucycles_ticks_"$arch"_"$x" \\\n') f.write(' -Dticks_setup=cpucycles_ticks_"$arch"_"$x"_setup \\\n') f.write(' -Dticks_close=cpucycles_ticks_"$arch"_"$x"_close \\\n') f.write(' -c "$arch"-"$x".c\n') f.write(' case $? in\n') f.write(' 0) break ;;\n') f.write(' 111) exit 111 ;;\n') f.write(' *) echo "skipping option that did not compile" ;;\n') f.write(' esac\n') f.write('done\n') os.chmod('build/%s/cpucycles/compile-ticks' % host,0o755) cpucyclesoptions = [] cpucyclesofiles = [] with open('cpucycles/options') as f: for line in f: line = line.strip() if line == '': continue if line[0] == '#': continue base = line.split()[0] if not os.path.exists('cpucycles/%s.c' % base): continue cpucycles = base.split('-') if len(cpucycles) != 2: continue if cpucycles[0] not in (host,'default'): continue cpucyclesoptions += [cpucycles] cpucyclesoptions += [['default','zero']] # must be last for cpucycles in cpucyclesoptions: base = '-'.join(cpucycles) cpucyclesofiles += ['cpucycles/%s.o' % base] dirlinksym('build/%s/cpucycles'%host,'try-%s.c'%base,'../src/cpucycles/%s.c'%base) M = 'cpucycles/%s.o: cpucycles/try-%s.c cpucycles/try-default-zero.c\n' % (base,base) M += '\tcd cpucycles && ./compile-ticks %s %s\n' % tuple(cpucycles) M += '\n' makefile = M + makefile for fn in sorted(os.listdir('cpucycles')): if not fn.endswith('.c'): continue if '-' in fn: continue base = fn[:-2] cpucyclesofiles += ['cpucycles/%s.o' % base] dirlinksym('build/%s/cpucycles'%host,fn,'../src/cpucycles/%s'%fn) M = 'cpucycles/%s.o: cpucycles/%s.c\n' % (base,base) M += '\tscripts/compiledefault cpucycles %s c\n' % base M += '\n' makefile = M + makefile with open('build/%s/cpucycles/options.inc' % host,'w') as f: f.write('#define NUMOPTIONS %d\n' % len(cpucyclesoptions)) f.write('#define DEFAULTOPTION (NUMOPTIONS-1)\n') f.write('\n') for cpucycles in cpucyclesoptions: f.write('extern long long cpucycles_ticks_%s_%s_setup(void);\n' % (cpucycles[0],cpucycles[1])) f.write('extern long long cpucycles_ticks_%s_%s(void);\n' % (cpucycles[0],cpucycles[1])) f.write('extern void cpucycles_ticks_%s_%s_close(void);\n' % (cpucycles[0],cpucycles[1])) f.write('\n') f.write('static struct {\n') f.write(' const char *implementation;\n') f.write(' long long (*ticks_setup)(void);\n') f.write(' long long (*ticks)(void);\n') f.write(' void (*ticks_close)(void);\n') f.write('} options[NUMOPTIONS] = {\n') for cpucycles in cpucyclesoptions: f.write('{ "%s-%s", cpucycles_ticks_%s_%s_setup, cpucycles_ticks_%s_%s, cpucycles_ticks_%s_%s_close },\n' % (cpucycles[0],cpucycles[1],cpucycles[0],cpucycles[1],cpucycles[0],cpucycles[1],cpucycles[0],cpucycles[1])) f.write('} ;\n') dirlinksym('build/%s/scripts'%host,'staticlib','../src/scripts-build/staticlib') M = 'package/lib/libcpucycles.a: scripts/staticlib %s\n' % ' '.join(cpucyclesofiles) M += '\tscripts/staticlib %s\n' % ' '.join(cpucyclesofiles) M += '\n' makefile = M + makefile with open('build/%s/scripts/sharedlib' % host,'w') as f: f.write('#!/bin/sh\n') f.write('\n') f.write('%s -shared \\\n' % firstcompiler) if rpath: f.write(' -Wl,-rpath=%s \\\n' % rpath) f.write(f' -Wl,-{soname},libcpucycles.{so1} \\\n') f.write(f' -o package/lib/libcpucycles.{so1} \\\n') f.write(' "$@"\n') f.write(f'chmod 644 package/lib/libcpucycles.{so1}\n') os.chmod('build/%s/scripts/sharedlib' % host,0o755) M = f'package/lib/libcpucycles.{so1}: scripts/sharedlib %s\n' % ' '.join(cpucyclesofiles) M += '\tscripts/sharedlib %s\n' % ' '.join(cpucyclesofiles) M += '\n' makefile = M + makefile M = f'package/lib/libcpucycles.{so}: package/lib/libcpucycles.{so1}\n' M += f'\trm -f package/lib/libcpucycles.{so}\n' M += f'\tln -s libcpucycles.{so1} package/lib/libcpucycles.{so}\n' M += '\n' makefile = M + makefile # ----- command os.makedirs('build/%s/command'%host) for c in sorted(os.listdir('command')): dirlinksym('build/%s/command'%host,c,'../src/command/%s'%c) dirlinksym('build/%s/command'%host,'bin','../package/bin') dirlinksym('build/%s/command'%host,'lib','../package/lib') dirlinksym('build/%s/command'%host,'include','../package/include') with open('build/%s/command/link' % host,'w') as f: f.write('#!/bin/sh\n') f.write('target="$1"; shift\n') f.write('%s \\\n' % firstcompiler) f.write(' -o "$target" "$@"\n') os.chmod('build/%s/command/link' % host,0o755) commands = [] for fn in sorted(os.listdir('command')): if not fn.endswith('.sh'): continue base = fn[:-3] M = f'package/bin/{base}: command/{base}.sh\n' M += f'\tcp command/{base}.sh package/bin/{base}\n' M += f'\tchmod 755 package/bin/{base}\n' M += '\n' makefile = M + makefile commands += ['package/bin/%s' % base] for fn in sorted(os.listdir('command')): if not fn.endswith('.c'): continue libs = ['libcpucycles'] base = fn[:-2] M = 'command/%s.o: command/%s.c\n' % (base,base) M += '\tscripts/compiledefault command %s c -I include\n' % base M += '\n' makefile = M + makefile M = 'package/bin/%s: command/%s.o%s\n' % (base,base,''.join(' package/lib/%s.%s' % (x,so) for x in libs)) M += f'\tcd command && ./link bin/%s %s.o%s {syslibs}\n' % (base,base,''.join(' lib/%s.%s' % (x,so) for x in libs)) M += '\n' makefile = M + makefile commands += ['package/bin/%s' % base] M = 'commands: %s\n' % ' '.join(commands) M += '\n' makefile = M + makefile # ----- make install M = 'install: scripts/install default\n' M += '\tscripts/install %s\n' % prefix M += '\n' makefile = M + makefile # ----- make default M = f'default: package/lib/libcpucycles.a package/lib/libcpucycles.{so} package/lib/libcpucycles.{so1} \\\n' M += 'commands\n' M += '\n' makefile = M + makefile with open('build/%s/Makefile' % host,'w') as f: f.write(makefile) # ----- build/0, build/Makefile dirlinksym('build','0',host) with open('build/Makefile','w') as f: f.write('default:\n') f.write('\tcd %s && $(MAKE)\n' % host) f.write('\n') f.write('install:\n') f.write('\tcd %s && $(MAKE) install\n' % host) f.write('\n') f.write('clean:\n') f.write('\trm -r %s\n' % host) # ----- configure.log log('configure done') with open('build/%s/configure.log'%host,'a') as f: f.write(configurelog) with open('build/%s/configure.log.latest'%host,'w') as f: f.write(configurelog) libcpucycles-20260901/cpucycles/0000755000000000000000000000000015245636444015145 5ustar rootrootlibcpucycles-20260901/cpucycles/amd64-perfpmc.c0000644000000000000000000000501215245636444017654 0ustar rootroot// version 20260105 // public domain // djb // 20260105 djb: disable GenuineIntel here given perf bug on e-cores (rather than trusting wrapper to detect perfpmcff being faster) // 20260105 djb: go back to buf->index for AMD support // 20251226 djb: add ticks_close() // 20251226 djb: include xkernel loop and xhv loop // 20251226 djb: skip mmap // 20251226 djb: always use rdpmc with PERF_FIXED_CTR1 (works around perf on e.g. 6.1.0 returning index=0 for e-cores) // 20251225 djb: use PERF_FLAG_FD_CLOEXEC // 20230105 djb: adapted from supercop/cpucycles/amd64rdpmc.c #include #include #include #include #include #include #include #include "cpucycles_internal.h" #include "cpuid_intel.h" static struct perf_event_mmap_page *buf = 0; long long ticks(void) { long long result; unsigned int seq; long long index; long long offset; do { seq = buf->lock; asm volatile("" ::: "memory"); index = buf->index; offset = buf->offset; asm volatile("rdpmc;shlq $32,%%rdx;orq %%rdx,%%rax" : "=a"(result) : "c"(index-1) : "%rdx"); asm volatile("" ::: "memory"); } while (buf->lock != seq); result += offset; result &= 0xffffffffffff; return result; } #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif static int fdperf = -1; void ticks_close(void) { if (fdperf >= 0) close(fdperf); fdperf = -1; } static long long abort_on_intel(void) { if (cpuid_says_genuineintel()) abort(); return 0; } long long ticks_setup(void) { int xkernel,xhv; if (!cpucycles_works(abort_on_intel)) return cpucycles_SKIP; if (fdperf == -1) { // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; fdperf = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf != -1) { buf = mmap(NULL,sysconf(_SC_PAGESIZE),PROT_READ,MAP_SHARED,fdperf,0); break; } } if (fdperf != -1) break; } if (fdperf == -1) return cpucycles_SKIP; } if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/amd64-perfpmcff.c0000644000000000000000000000514015245636444020172 0ustar rootroot// version 20260901 // public domain // djb // 20260901 djb: skip this counter for PMC below v3 or below 48 bits // 20260901 djb: use /sys/bus/event_source/devices/cpu_atom/type // 20260625 djb: add second fd for atom cores, sigh // 20260105 djb: forked from amd64-perfpmc.c // 20251226 djb: add ticks_close() // 20251226 djb: include xkernel loop and xhv loop // 20251226 djb: skip mmap // 20251226 djb: always use rdpmc with PERF_FIXED_CTR1 (works around perf on e.g. 6.1.0 returning index=0 for e-cores) // 20251225 djb: use PERF_FLAG_FD_CLOEXEC // 20230105 djb: adapted from supercop/cpucycles/amd64rdpmc.c #include #include #include #include #include #include #include "cpucycles_internal.h" #include "cpuid_intel.h" #include "atom_type.h" long long ticks(void) { long long result; asm volatile("rdpmc;shlq $32,%%rdx;orq %%rdx,%%rax" : "=a"(result) : "c"((1<<30)|1) : "%rdx"); return result; } #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif // XXX: maybe allow more fds for more cpu_* directories // XXX: maybe ask linux to add simpler API static int fdperf = -1; static int fdperfatom = -1; void ticks_close(void) { if (fdperfatom >= 0) close(fdperfatom); fdperfatom = -1; if (fdperf >= 0) close(fdperf); fdperf = -1; } static long long abort_on_narrow_pmc(void) { if (!cpuid_wide_pmc()) abort(); return 0; } long long ticks_setup(void) { int xkernel,xhv; if (!cpucycles_works(abort_on_narrow_pmc)) return cpucycles_SKIP; if (fdperf == -1) { atom_type_init(); // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; fdperf = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf != -1) { #ifdef PERF_PMU_TYPE_SHIFT if (atom_type > 0) { attr.config |= ((long long) atom_type) << PERF_PMU_TYPE_SHIFT; fdperfatom = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); } #endif break; } } if (fdperf != -1) break; } if (fdperf == -1) return cpucycles_SKIP; } if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/amd64-pmcff.c0000644000000000000000000000121715245636444017316 0ustar rootroot// version 20260105 // public domain // djb // 20260105 djb: rename from pmc to pmcff (for the use of fixed-function counters) // 20251226 djb: add ticks_close() // 20251226 djb: rename previous as amd64-perf-pmc.c; remove perf from this version // 20230105 djb: adapted from supercop/cpucycles/amd64rdpmc.c #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("rdpmc;shlq $32,%%rdx;orq %%rdx,%%rax" : "=a"(result) : "c"((1<<30)|1) : "%rdx"); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/amd64-tsc.c0000644000000000000000000000113515245636444017013 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: use cpuid_tsc_invariant_frequency() #ifdef _MSC_VER #include #else #include #endif #include "cpucycles_internal.h" #include "cpuid_intel.h" long long ticks(void) { return __rdtsc(); } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; if (cpucycles_works(cpuid_tsc_invariant_frequency)) { long long freq = cpuid_tsc_invariant_frequency(); if (freq) return freq; } return cpucycles_MAYBECYCLECOUNTER; } libcpucycles-20260901/cpucycles/amd64-tscasm.c0000644000000000000000000000131715245636444017516 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: use cpuid_tsc_invariant_frequency() // 20230105 djb: adapted from supercop/cpucycles/amd64tscfreq.c #include "cpucycles_internal.h" #include "cpuid_intel.h" long long ticks(void) { unsigned long long result; asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax" : "=a"(result) :: "%rdx"); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; if (cpucycles_works(cpuid_tsc_invariant_frequency)) { long long freq = cpuid_tsc_invariant_frequency(); if (freq) return freq; } return cpucycles_MAYBECYCLECOUNTER; } libcpucycles-20260901/cpucycles/arm32-1176.c0000644000000000000000000000124215245636444016630 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20250925 djb: have enable return long long instead of long // 20240114 djb: adapted from arm32-cortex.c #include "cpucycles_internal.h" long long ticks(void) { unsigned int result; asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(result)); return (unsigned long long) result; } static long long enable(void) { asm volatile("mcr p15, 0, %0, c15, c12, 0" :: "r"(17)); return 0; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(enable)) return cpucycles_SKIP; if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_EXTEND32; } libcpucycles-20260901/cpucycles/arm32-cortex.c0000644000000000000000000000145715245636444017546 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20250925 djb: have enable return long long instead of long // 20230105 djb: adapted from supercop/cpucycles/cortex.c #include "cpucycles_internal.h" long long ticks(void) { unsigned int result; asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(result)); return (unsigned long long) result; } static long long enable(void) { asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(17)); asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f)); asm volatile("mcr p15, 0, %0, c9, c12, 3" :: "r"(0x8000000f)); return 0; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(enable)) return cpucycles_SKIP; if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_EXTEND32; } libcpucycles-20260901/cpucycles/arm64-perfpmc.c0000644000000000000000000000310715245636444017675 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: wrap inside perf_event_open (otherwise current kernels disable pmccntr if another process uses perf) // 20251226 djb: forked from arm64-pmc.c #include #include #include #include #include #include #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("mrs %0, PMCCNTR_EL0" : "=r" (result)); return result; } #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif static int fdperf = -1; void ticks_close(void) { if (fdperf >= 0) close(fdperf); fdperf = -1; } long long ticks_setup(void) { int xkernel,xhv; if (fdperf == -1) { // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; attr.config1 = 3; // 1 (user enable) + 2 (64-bit) fdperf = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf != -1) break; } if (fdperf != -1) break; } if (fdperf == -1) return cpucycles_SKIP; } if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/arm64-pmc.c0000644000000000000000000000073315245636444017022 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: doc reorg, same code // 20230105 djb: adapted from supercop/cpucycles/armv8.c #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("mrs %0, PMCCNTR_EL0" : "=r" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/arm64-vct.c0000644000000000000000000000073215245636444017036 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: doc reorg, same code // 20230105 djb: adapted from supercop/cpucycles/vct.c #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("mrs %0, CNTVCT_EL0" : "=r" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_FINDMULTIPLIER; } libcpucycles-20260901/cpucycles/atom_type.h0000644000000000000000000000063715245636444017325 0ustar rootroot#ifndef atom_type_h #define atom_type_h #include static long long atom_type = -1; static void atom_type_init(void) { FILE *f = 0; int s = 0; if (atom_type != -1) return; atom_type = 0; // XXX: could use, e.g., 10 as fallback f = fopen("/sys/bus/event_source/devices/cpu_atom/type","r"); if (!f) return; s = fscanf(f,"%lld",&atom_type); fclose(f); if (s < 1) atom_type = 0; } #endif libcpucycles-20260901/cpucycles/cpucycles.h0000644000000000000000000000121115245636444017303 0ustar rootroot// version 20230115 // public domain // djb // 20230115 djb: cpucycles_version() // 20230114 djb: improve punctuation #ifndef cpucycles_h #define cpucycles_h #ifdef __cplusplus extern "C" { #endif extern long long (*cpucycles)(void) __attribute__((visibility("default"))); extern const char *cpucycles_implementation(void) __attribute__((visibility("default"))); extern const char *cpucycles_version(void) __attribute__((visibility("default"))); extern long long cpucycles_persecond(void) __attribute__((visibility("default"))); extern void cpucycles_tracesetup(void) __attribute__((visibility("default"))); #ifdef __cplusplus } #endif #endif libcpucycles-20260901/cpucycles/cpucycles_internal.h0000644000000000000000000000077315245636444021213 0ustar rootroot// version 20230105 // public domain // djb #ifndef cpucycles_internal_h #define cpucycles_internal_h extern long long cpucycles_init(void); extern long long cpucycles_microseconds(void); extern int cpucycles_works(long long (*)(void)); // return values from ticks_setup(): #define cpucycles_SKIP (0) #define cpucycles_CYCLECOUNTER (-1) #define cpucycles_MAYBECYCLECOUNTER (-2) #define cpucycles_FINDMULTIPLIER (-3) #define cpucycles_EXTEND32 (-32) // and positive values mean known ticks/second #endif libcpucycles-20260901/cpucycles/cpuid_intel.h0000644000000000000000000000446215245636444017623 0ustar rootroot#ifndef cpuid_intel_h #define cpuid_intel_h #ifdef __FILC__ #include static void cpuid_0(unsigned int leaf,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d) { __get_cpuid(leaf,a,b,c,d); } #elif defined(_MSC_VER) static void cpuid_0(unsigned int leaf,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d) { int abcd[4]; __cpuidex(abcd,leaf,0); *a = abcd[0]; *b = abcd[1]; *c = abcd[2]; *d = abcd[3]; } #else static void cpuid_0(unsigned int op,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d) { asm volatile("cpuid" : "=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d) : "a"(op) : "memory"); } #endif __attribute__((unused)) static long long cpuid_says_genuineintel(void) { unsigned int a,b,c,d; cpuid_0(0,&a,&b,&c,&d); return b == 0x756e6547 && d == 0x49656e69 && c == 0x6c65746e; } __attribute__((unused)) static long long cpuid_wide_pmc(void) { unsigned int a,b,c,d; cpuid_0(0,&a,&b,&c,&d); if (a < 0x0a) return 0; cpuid_0(0x0a,&a,&b,&c,&d); if ((a & 255) <= 2) return 0; if (((d >> 5) & 255) < 48) return 0; return 1; } // 0 if not clear that tsc is invariant __attribute__((unused)) static long long cpuid_tsc_invariant_frequency(void) { unsigned int a,b,c,d,top,bot; cpuid_0(0x80000000,&a,&b,&c,&d); if (a < 0x80000007) return 0; cpuid_0(0x80000007,&a,&b,&c,&d); if (!(d & 0x100)) return 0; cpuid_0(0,&a,&b,&c,&d); if (a < 0x15) return 0; cpuid_0(0x15,&bot,&top,&c,&d); if (!c) { // see "Nominal Core Crystal Clock Frequency" exception table in intel manual cpuid_0(0x1,&a,&b,&c,&d); switch(a & 0x0fff0ff0) { case 0x000406e0: // skylake case 0x000506e0: // skylake case 0x000806e0: // kaby lake (or comet lake) case 0x000906e0: // kaby lake (or coffee lake) case 0x000a0650: // comet lake case 0x000a0660: // comet lake c = 24000000; break; // "6th and 7th generation Intel Core processors and Intel Xeon W Processor Family" case 0x00050650: // cascade lake c = 25000000; break; // "Intel Xeon Scalable Processor Family with CPUID signature 06_55H" case 0x000506c0: // goldmont c = 19200000; break; // "Next Generation Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH" } } return (top * (long long) c) / bot; } #endif libcpucycles-20260901/cpucycles/default-gettimeofday.c0000644000000000000000000000043515245636444021416 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: first version #include "cpucycles_internal.h" long long ticks_setup(void) { return 1000000; } void ticks_close(void) { } long long ticks(void) { return cpucycles_microseconds(); } libcpucycles-20260901/cpucycles/default-mach.c0000644000000000000000000000057415245636444017651 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: first version #include #include "cpucycles_internal.h" long long ticks(void) { return mach_absolute_time(); } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_FINDMULTIPLIER; } libcpucycles-20260901/cpucycles/default-monotonic.c0000644000000000000000000000075415245636444020746 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: doc reorg, same code // 20230105 djb: adapted from supercop/cpucycles/monotonic.c #include #include long long ticks_setup(void) { return 1000000000; } void ticks_close(void) { } long long ticks(void) { struct timespec t; long long result; clock_gettime(CLOCK_MONOTONIC,&t); result = t.tv_sec; result *= 1000000000; result += t.tv_nsec; return result; } libcpucycles-20260901/cpucycles/default-perfevent.c0000644000000000000000000001333315245636444020734 0ustar rootroot// version 20260901 // public domain // djb // 20260901 djb: use /sys/bus/event_source/devices/cpu_atom/type // 20260625 djb: mark this as CYCLECOUNTER despite concerns about layers screwing this up // 20260625 djb: add second fd for atom cores, sigh // 20251226 djb: add ticks_close() // 20251225 djb: use PERF_FLAG_FD_CLOEXEC // 20250925 djb: do disable-enable (suggested by jim apple re graviton 3), but only if read() seems to always return 0 // 20250925 djb: try all possible exclude combinations // 20230106 djb: read() into int64_t instead of long long // 20230106 djb: add comment on RUNNING/ENABLED // 20230105 djb: adapted from supercop/cpucycles/perfevent.c /* This code intentionally avoids dividing by the PERF_FORMAT_TOTAL_TIME_RUNNING/ENABLED ratio. The motivation for that ratio is as follows: * A typical CPU has a limited number of performance-monitoring counters active at once. For example, there are 8 "programmable" counters on Intel Skylake. * "perf stat" allows the user to enable more counters. The OS kernel periodically (e.g., every millisecond) changes the limited number of active hardware counters to a new subset of the enabled counters, and "perf stat" reports PERF_FORMAT_TOTAL_TIME_RUNNING/ENABLED for each counter, the fraction of time spent with that counter running. For long-running programs, dividing the hardware counter by RUNNING/ENABLED usually produces a reasonable estimate of what the count would have been without competition from other counters. A fixable problem with this multiplexing of counters is that the kernel appears to simply cycle through counters, so unlucky programs can trigger moiré effects. The fix is to select random subsets of counters. A more fundamental problem is that cpucycles() has to be usable for timing short subroutines, including subroutines so short that the OS has no opportunity to change from one selection of counters to another. Say RUNNING is 0; should cpucycles() then divide by 0? If a caller runs cpucycles(), X(), cpucycles(), X(), etc., and the cycle counter happens to be enabled for only 80% of the runs of X(), then simply computing the median difference of adjacent cycle counts, with no scaling, will filter out the zeros and correctly compute the cost of X. Averages won't (without scaling), but averages have other problems, such as being heavily influenced by interrupts. (Omitting kernel time from perf results does not remove the influence of interrupts on caches.) Given the importance of cycle counting, it is better to have cycle counters always running. For example, on Skylake, Intel provides the 8 "programmable" counters on top of a separate cycle counter ("fixed counter 1"), so there is no good reason for the kernel to waste a "programmable" counter on a cycle counter, there is no good reason to turn the cycle counter off, and there is no good reason for RUNNING to be below ENABLED for the cycle counter. Of course, applications that use just one performance counter at a time don't have to worry about kernels getting this wrong, and don't have to worry about the possibility of getting noisy or invalid results on CPUs that have heavier constraints on the number of simultaneous counters. */ #include #include #include #include #include #include #include #include #include "cpucycles_internal.h" #include "atom_type.h" #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif static int fdperf[2] = {-1,-1}; static int de = 1; static int whichperf = 0; static int64_t lastresult = 0; long long ticks(void) { int64_t result; for (int loop = 0;loop < 2;++loop) { if (de) ioctl(fdperf[whichperf],PERF_EVENT_IOC_DISABLE,0); if (read(fdperf[whichperf],&result,sizeof result) < sizeof result) result = 0; if (de) ioctl(fdperf[whichperf],PERF_EVENT_IOC_ENABLE,0); if (result != lastresult) break; // the normal case if (fdperf[1] == -1) break; whichperf = 1-whichperf; } lastresult = result; return result; } void ticks_close(void) { for (long long i = 0;i < 2;++i) { if (fdperf[i] >= 0) close(fdperf[i]); fdperf[i] = -1; } de = 1; whichperf = 0; lastresult = 0; } long long ticks_setup(void) { int xkernel,xhv,loop; if (fdperf[0] == -1) { atom_type_init(); // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.disabled = 1; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; fdperf[0] = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf[0] != -1) { #ifdef PERF_PMU_TYPE_SHIFT // XXX: see notes in amd64-perfpmcff.c if (atom_type > 0) { attr.config |= ((long long) atom_type) << PERF_PMU_TYPE_SHIFT; fdperf[1] = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); } #endif break; } } if (fdperf[0] != -1) break; } if (fdperf[0] == -1) return cpucycles_SKIP; ioctl(fdperf[0],PERF_EVENT_IOC_RESET,0); ioctl(fdperf[0],PERF_EVENT_IOC_ENABLE,0); if (fdperf[1] != -1) { ioctl(fdperf[1],PERF_EVENT_IOC_RESET,0); ioctl(fdperf[1],PERF_EVENT_IOC_ENABLE,0); } } for (loop = 0;loop < 100;++loop) { int64_t result; if (read(fdperf[0],&result,sizeof result) < sizeof result) result = 0; if (result != 0) { de = 0; break; } } return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/default-zero.c0000644000000000000000000000041515245636444017712 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: first version #include "cpucycles_internal.h" long long ticks_setup(void) { return cpucycles_SKIP; } void ticks_close(void) { } long long ticks(void) { return 0; } libcpucycles-20260901/cpucycles/loong64-rdtime.c0000644000000000000000000000063615245636444020070 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20250924 djb: first version #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("rdtime.d %0, $zero\n" : "=r" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_FINDMULTIPLIER; } libcpucycles-20260901/cpucycles/mips64-cc.c0000644000000000000000000000160015245636444017013 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/mips.c // mips32 release 2 instruction rdhwr // 7c02103b: read hwr#2 (cycle count) into $2 // 7c02183b: read hwr#3 (cycle-count multiplier) into $2 #include "cpucycles_internal.h" static unsigned int multiplier = 0; static long long multiplier_set(void) { asm volatile(".long 0x7c02183b; move %0,$2" : "=r"(multiplier) : : "$2"); return multiplier; } long long ticks(void) { unsigned int result; asm volatile(".long 0x7c02103b; move %0,$2" : "=r"(result) :: "$2"); result *= multiplier; return (unsigned long long) result; } void ticks_close(void) { multiplier = 0; } long long ticks_setup(void) { if (!cpucycles_works(multiplier_set)) return cpucycles_SKIP; if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_EXTEND32; } libcpucycles-20260901/cpucycles/options0000644000000000000000000000054615245636444016570 0ustar rootrootamd64-perfpmcff amd64-perfpmc amd64-pmcff amd64-tsc amd64-tscasm arm32-cortex arm32-1176 arm64-perfpmc arm64-pmc arm64-vct loong64-rdtime mips64-cc ppc32-mftb ppc64-mftb riscv32-perfrdcycle riscv32-rdcycle riscv64-perfrdcycle riscv64-rdcycle s390x-stckf sparc64-rdtick x86-tsc x86-tscasm default-perfevent default-mach default-monotonic default-gettimeofday libcpucycles-20260901/cpucycles/ppc32-mftb.c0000644000000000000000000000117315245636444017170 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/powerpccpuinfo.c #include "cpucycles_internal.h" long long ticks(void) { unsigned int high, low, newhigh; unsigned long long result; do { asm volatile( "mftbu %0; mftb %1; mftbu %2" : "=r" (high), "=r" (low), "=r" (newhigh) ); } while (newhigh != high); result = high; result <<= 32; result |= low; return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_FINDMULTIPLIER; } libcpucycles-20260901/cpucycles/ppc64-mftb.c0000644000000000000000000000117315245636444017175 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/powerpccpuinfo.c #include "cpucycles_internal.h" long long ticks(void) { unsigned int high, low, newhigh; unsigned long long result; do { asm volatile( "mftbu %0; mftb %1; mftbu %2" : "=r" (high), "=r" (low), "=r" (newhigh) ); } while (newhigh != high); result = high; result <<= 32; result |= low; return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_FINDMULTIPLIER; } libcpucycles-20260901/cpucycles/riscv32-perf-rdcycle.c0000644000000000000000000000337215245636444021166 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: wrap inside perf_event_open (otherwise current kernels disable rdcycle) // 20251226 djb: fork from riscv32-rdcycle.c #include #include #include #include #include #include #include "cpucycles_internal.h" long long ticks(void) { unsigned int low, high, newhigh; unsigned long long result; asm volatile( "start%=:\n" "rdcycleh %0\n" "rdcycle %1\n" "rdcycleh %2\n" "bne %0, %2, start%=\n" : "=r"(high), "=r"(low), "=r"(newhigh)); result = high; result <<= 32; result |= low; return result; } #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif static int fdperf = -1; void ticks_close(void) { if (fdperf >= 0) close(fdperf); fdperf = -1; } long long ticks_setup(void) { int xkernel,xhv; if (fdperf == -1) { // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; fdperf = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf != -1) break; } if (fdperf != -1) break; } if (fdperf == -1) return cpucycles_SKIP; } if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/riscv32-rdcycle.c0000644000000000000000000000134715245636444020234 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/riscv.c, which has code from djb and Romain Dolbeau #include "cpucycles_internal.h" long long ticks(void) { unsigned int low, high, newhigh; unsigned long long result; asm volatile( "start%=:\n" "rdcycleh %0\n" "rdcycle %1\n" "rdcycleh %2\n" "bne %0, %2, start%=\n" : "=r"(high), "=r"(low), "=r"(newhigh)); result = high; result <<= 32; result |= low; return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/riscv64-perfrdcycle.c0000644000000000000000000000275315245636444021120 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: wrap inside perf_event_open (otherwise current kernels disable rdcycle) // 20251226 djb: fork from riscv64-rdcycle.c #include #include #include #include #include #include #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("rdcycle %0" : "=r" (result)); return result; } #ifndef PERF_FLAG_FD_CLOEXEC #define PERF_FLAG_FD_CLOEXEC 0 #endif static int fdperf = -1; void ticks_close(void) { if (fdperf >= 0) close(fdperf); fdperf = -1; } long long ticks_setup(void) { int xkernel,xhv; if (fdperf == -1) { // prefer to exclude if platform supports that // but fall back to non-exclude if necessary for (xkernel = 1;xkernel >= 0;--xkernel) { for (xhv = 1;xhv >= 0;--xhv) { static struct perf_event_attr attr; memset(&attr,0,sizeof attr); attr.type = PERF_TYPE_HARDWARE; attr.size = sizeof(struct perf_event_attr); attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = xkernel; attr.exclude_hv = xhv; fdperf = syscall(__NR_perf_event_open,&attr,0,-1,-1,PERF_FLAG_FD_CLOEXEC); if (fdperf != -1) break; } if (fdperf != -1) break; } if (fdperf == -1) return cpucycles_SKIP; } if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/riscv64-rdcycle.c0000644000000000000000000000073015245636444020234 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/riscv.c, which has code from djb and Romain Dolbeau #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("rdcycle %0" : "=r" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/s390x-stckf.c0000644000000000000000000000071315245636444017310 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230106 djb: adapted from sparc64-rdtick.c #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("stckf 0(%0)" :: "a"(&result) : "memory","cc"); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return 4096000000; // manual says 2^12 per microsecond } libcpucycles-20260901/cpucycles/sparc64-rdtick.c0000644000000000000000000000066515245636444020060 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20230105 djb: adapted from supercop/cpucycles/sparccpuinfo.c #include "cpucycles_internal.h" long long ticks(void) { long long result; asm volatile("rd %%tick,%0" : "=r" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; return cpucycles_CYCLECOUNTER; } libcpucycles-20260901/cpucycles/wrapper.c0000644000000000000000000002543415245636444017001 0ustar rootroot// version 20260625 // public domain // djb #define ORDERBUMP 10 #define EXTENDBUMP 300 #define OFFCOREBUMP 1000 #define CALLS 1000 #define ESTIMATES 3 // 20260625 djb: increase OFFCOREBUMP to 1000 // 20260625 djb: define some tunables at top // 20260105 djb: add orderbump // 20260105 djb: catch abort() in works(); bump version // 20251226 djb: add ticks_close() // 20251226 djb: use sigjmp_buf instead of jmp_buf (this matters on solaris) // 20250925 djb: loosen 0.1 to 0.2 for FINDMULTIPLIER // 20230115 djb: cpucycles_version() // 20230106 djb: support "cpu MHz static" (ibm z15) // 20230105 djb: first version; includes some pieces adapted from supercop #include #include #include #include #include #include #include #include #include #include "cpucycles.h" #include "cpucycles_internal.h" static int tracesetup = 0; void cpucycles_tracesetup(void) { tracesetup = 1; } static sigjmp_buf crash_jmp; static void crash(int s) { siglongjmp(crash_jmp,1); } int cpucycles_works(long long (*ticks)(void)) { volatile int result = 0; struct sigaction old_sigill; struct sigaction old_sigfpe; struct sigaction old_sigbus; struct sigaction old_sigsegv; struct sigaction old_sigabrt; struct sigaction crash_action; memset(&crash_action,0,sizeof crash_action); crash_action.sa_handler = crash; sigaction(SIGILL,0,&old_sigill); sigaction(SIGFPE,0,&old_sigfpe); sigaction(SIGBUS,0,&old_sigbus); sigaction(SIGSEGV,0,&old_sigsegv); sigaction(SIGABRT,0,&old_sigabrt); if (!sigsetjmp(crash_jmp,1)) { sigaction(SIGILL,&crash_action,0); sigaction(SIGFPE,&crash_action,0); sigaction(SIGBUS,&crash_action,0); sigaction(SIGSEGV,&crash_action,0); sigaction(SIGABRT,&crash_action,0); ticks(); result = 1; } sigaction(SIGILL,&old_sigill,0); sigaction(SIGFPE,&old_sigfpe,0); sigaction(SIGBUS,&old_sigbus,0); sigaction(SIGSEGV,&old_sigsegv,0); sigaction(SIGABRT,&old_sigabrt,0); return result; } static double osfreq(void) { FILE *f; char *x; double result; int s; f = fopen("/etc/cpucyclespersecond", "r"); if (f) { s = fscanf(f,"%lf",&result); fclose(f); if (s > 0) return result; } f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "r"); if (f) { s = fscanf(f,"%lf",&result); fclose(f); if (s > 0) return 1000.0 * result; } f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "r"); if (f) { s = fscanf(f,"%lf",&result); fclose(f); if (s > 0) return 1000.0 * result; } f = fopen("/sys/devices/system/cpu/cpu0/clock_tick", "r"); if (f) { s = fscanf(f,"%lf",&result); fclose(f); if (s > 0) return result; } f = fopen("/proc/cpuinfo","r"); if (f) { for (;;) { s = fscanf(f,"cpu MHz : %lf",&result); if (s > 0) break; if (s == 0) s = fscanf(f,"%*[^\n]\n"); if (s < 0) { result = 0; break; } } fclose(f); if (result) return 1000000.0 * result; } f = fopen("/proc/cpuinfo","r"); if (f) { for (;;) { s = fscanf(f,"clock : %lf",&result); if (s > 0) break; if (s == 0) s = fscanf(f,"%*[^\n]\n"); if (s < 0) { result = 0; break; } } fclose(f); if (result) return 1000000.0 * result; } f = fopen("/proc/cpuinfo","r"); if (f) { for (;;) { s = fscanf(f,"cpu MHz static : %lf",&result); if (s > 0) break; if (s == 0) s = fscanf(f,"%*[^\n]\n"); if (s < 0) { result = 0; break; } } fclose(f); if (result) return 1000000.0 * result; } f = popen("sysctl hw.cpufrequency 2>/dev/null","r"); if (f) { s = fscanf(f,"hw.cpufrequency: %lf",&result); pclose(f); if (s > 0) if (result > 0) return result; } f = popen("/usr/sbin/lsattr -E -l proc0 -a frequency 2>/dev/null","r"); if (f) { s = fscanf(f,"frequency %lf",&result); pclose(f); if (s > 0) return result; } f = popen("/usr/sbin/psrinfo -v 2>/dev/null","r"); if (f) { for (;;) { s = fscanf(f," The %*s processor operates at %lf MHz",&result); if (s > 0) break; if (s == 0) s = fscanf(f,"%*[^\n]\n"); if (s < 0) { result = 0; break; } } pclose(f); if (result) return 1000000.0 * result; } x = getenv("cpucyclespersecond"); if (x) { s = sscanf(x,"%lf",&result); if (s > 0) return result; } return 2399987654.0; } static long long persecond = 0; static const char *implementation = "none"; long long (*cpucycles)(void) = cpucycles_init; const char *cpucycles_implementation(void) { cpucycles(); return implementation; } long long cpucycles_persecond(void) { cpucycles(); return persecond; } const char *cpucycles_version(void) { return "20260901"; } // ----- cycle counter scaled from ticks static double cpucycles_scaled_scaling = 0; static long long cpucycles_scaled_offset = 0; static long long (*cpucycles_scaled_from)(void) = 0; static long long cpucycles_scaled(void) { return (cpucycles_scaled_from()-cpucycles_scaled_offset)*cpucycles_scaled_scaling; } // ----- cycle counter extended from 32-bit ticks static long long (*cpucycles_extend32_from)(void) = 0; static uint32_t cpucycles_extend32_prev_ticks; static long long cpucycles_extend32_prev_us; static long long cpucycles_extend32_prev_cycles; static void cpucycles_extend32_setup(void) { long long (*ticks)(void) = cpucycles_extend32_from; cpucycles_extend32_prev_ticks = ticks(); cpucycles_extend32_prev_us = cpucycles_microseconds(); cpucycles_extend32_prev_cycles = 0; } static long long cpucycles_extend32(void) { long long (*ticks)(void) = cpucycles_extend32_from; uint32_t new_ticks = ticks(); unsigned long long delta_ticks = new_ticks-cpucycles_extend32_prev_ticks; long long new_us = cpucycles_microseconds(); long long delta_us = new_us-cpucycles_extend32_prev_us; // assume that number of cycles cannot increase by 2^32 in 2ms if (delta_us < 1000) return cpucycles_extend32_prev_cycles+delta_ticks; cpucycles_extend32_prev_ticks = new_ticks; cpucycles_extend32_prev_us = new_us; if (delta_us >= 2000) { long long target = (delta_us*0.000001)*persecond; while (delta_ticks+2147483648ULL < target) delta_ticks += 4294967296ULL; } return cpucycles_extend32_prev_cycles += delta_ticks; } // ----- estimating cycles per tick long long cpucycles_microseconds(void) { struct timeval t; long long result; gettimeofday(&t,(struct timezone *) 0); result = t.tv_sec; result *= 1000000; result += t.tv_usec; return result; } static double estimate_cyclespertick(long long (*ticks)(void)) { long long t0,t1,us0,us1; t0 = ticks(); us0 = cpucycles_microseconds(); do { t1 = ticks(); us1 = cpucycles_microseconds(); } while (us1-us0 < 10000 || t1-t0 < 1000); if (t1 <= t0) return 0; t1 -= t0; us1 -= us0; return (persecond * 0.000001 * (double) us1) / (double) t1; } // ----- selecting an option #include "options.inc" long long cpucycles_init(void) { long long precision[NUMOPTIONS]; double scaling[NUMOPTIONS]; int only32[NUMOPTIONS]; long long bestprecision; long long bestopt; long long opt; long long orderbump = 0; persecond = osfreq(); for (opt = 0;opt < NUMOPTIONS;options[opt++].ticks_close()) { long long freq = options[opt].ticks_setup(); long long tries; precision[opt] = 0; scaling[opt] = 0; only32[opt] = 0; if (freq > 0) { scaling[opt] = persecond*1.0/freq; } else if (freq == cpucycles_CYCLECOUNTER) { scaling[opt] = 1.0; } else if (freq == cpucycles_EXTEND32) { only32[opt] = 1; scaling[opt] = 1.0; } else if (freq == cpucycles_MAYBECYCLECOUNTER) { scaling[opt] = 1.0; } else if (freq == cpucycles_FINDMULTIPLIER) { int ok = 0; double denom; long long loop; for (denom = 1;denom <= 1024;denom += denom) { double est[ESTIMATES]; for (loop = 0;loop < ESTIMATES;++loop) est[loop] = denom*estimate_cyclespertick(options[opt].ticks); scaling[opt] = (double) (long long) est[0]; if (scaling[opt] < est[0]-0.5) scaling[opt] += 1; if (scaling[opt] > est[0]+0.5) scaling[opt] -= 1; ok = 1; for (loop = 0;loop < ESTIMATES;++loop) { if (est[loop]-scaling[opt] > 0.2) ok = 0; if (scaling[opt]-est[loop] > 0.2) ok = 0; } if (ok) { scaling[opt] /= denom; break; } scaling[opt] = 0; } if (!ok) continue; } else { continue; } for (tries = 0;tries < 10;++tries) { long long t[CALLS+1]; long long ok = 1; long long i; if (scaling[opt] == 1.0) { for (i = 0;i <= CALLS;++i) t[i] = options[opt].ticks(); } else { double scalingopt = scaling[opt]; long long offset = options[opt].ticks(); for (i = 0;i <= CALLS;++i) t[i] = (options[opt].ticks()-offset)*scalingopt; } for (i = 0;i < CALLS;++i) if (t[i] > t[i+1]) ok = 0; if (t[0] == t[CALLS]) ok = 0; if (ok) { long long smallestdiff = 0; for (i = 0;i < CALLS;++i) { long long diff = t[i+1]-t[i]; if (diff <= 0) continue; if (smallestdiff == 0 || diff < smallestdiff) smallestdiff = diff; } precision[opt] = smallestdiff; // tilt selection towards more robust counters if (freq > 0 || freq == cpucycles_MAYBECYCLECOUNTER || freq == cpucycles_FINDMULTIPLIER) precision[opt] += OFFCOREBUMP; if (freq == cpucycles_EXTEND32) precision[opt] += EXTENDBUMP; precision[opt] += orderbump; orderbump += ORDERBUMP; break; } // otherwise keep trying // since !ok can be caused by overflow // or by core swap } } if (tracesetup) { for (opt = 0;opt < NUMOPTIONS;++opt) printf("cpucycles tracesetup %lld %s precision %lld scaling %lf only32 %d\n" ,opt,options[opt].implementation,precision[opt],scaling[opt],only32[opt]); } bestopt = DEFAULTOPTION; bestprecision = 0; for (opt = 0;opt < NUMOPTIONS;++opt) if (precision[opt] > 0) if (!bestprecision || precision[opt] < bestprecision) { bestopt = opt; bestprecision = precision[opt]; } options[bestopt].ticks_setup(); implementation = options[bestopt].implementation; if (scaling[bestopt] == 1.0) { if (only32[bestopt]) { cpucycles_extend32_from = options[bestopt].ticks; cpucycles_extend32_setup(); cpucycles = cpucycles_extend32; } else { cpucycles = options[bestopt].ticks; } } else { cpucycles_scaled_scaling = scaling[bestopt]; cpucycles_scaled_from = options[bestopt].ticks; cpucycles_scaled_offset = cpucycles_scaled_from(); cpucycles = cpucycles_scaled; } return cpucycles(); } libcpucycles-20260901/cpucycles/x86-tsc.c0000644000000000000000000000113515245636444016525 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: use cpuid_tsc_invariant_frequency() #ifdef _MSC_VER #include #else #include #endif #include "cpucycles_internal.h" #include "cpuid_intel.h" long long ticks(void) { return __rdtsc(); } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; if (cpucycles_works(cpuid_tsc_invariant_frequency)) { long long freq = cpuid_tsc_invariant_frequency(); if (freq) return freq; } return cpucycles_MAYBECYCLECOUNTER; } libcpucycles-20260901/cpucycles/x86-tscasm.c0000644000000000000000000000113215245636444017223 0ustar rootroot// version 20251226 // public domain // djb // 20251226 djb: add ticks_close() // 20251226 djb: use cpuid_tsc_invariant_frequency() #include "cpucycles_internal.h" #include "cpuid_intel.h" long long ticks(void) { long long result; asm volatile(".byte 15;.byte 49" : "=A" (result)); return result; } void ticks_close(void) { } long long ticks_setup(void) { if (!cpucycles_works(ticks)) return cpucycles_SKIP; if (cpucycles_works(cpuid_tsc_invariant_frequency)) { long long freq = cpuid_tsc_invariant_frequency(); if (freq) return freq; } return cpucycles_MAYBECYCLECOUNTER; } libcpucycles-20260901/doc/0000755000000000000000000000000015245636444013720 5ustar rootrootlibcpucycles-20260901/doc/api.md0000644000000000000000000000316215245636444015015 0ustar rootroot### NAME cpucycles - count CPU cycles ### SYNOPSIS #include long long count = cpucycles(); long long persecond = cpucycles_persecond(); const char *implementation = cpucycles_implementation(); const char *version = cpucycles_version(); Link with `-lcpucycles`. Old systems may also need `-lrt`. ### DESCRIPTION `cpucycles()` returns an estimate for the number of CPU cycles that have occurred since an unspecified time in the past (perhaps system boot, perhaps program startup). Accessing true cycle counters can be difficult on some CPUs and operating systems. `cpucycles()` does its best to produce accurate results, but selects a low-precision counter if the only other option is failure. `cpucycles_persecond()` returns an estimate for the number of CPU cycles per second. This estimate comes from `/etc/cpucyclespersecond` if that file exists, otherwise from various OS mechanisms, otherwise from the `cpucyclespersecond` environment variable if that is set, otherwise 2399987654. `cpucycles_implementation()` returns the name of the counter in use: e.g., `"amd64-perfpmc"`. `cpucycles_version()` returns the `libcpucycles` version number as a string: e.g., `"20260901"`. Results of `cpucycles_implementation()` should be interpreted relative to `cpucycles_version()`. `cpucycles` is actually a function pointer. The first call to `cpucycles()` or `cpucycles_persecond()` or `cpucycles_implementation()` selects one of the available counters and updates the `cpucycles` pointer accordingly. Subsequent calls to `cpucycles()` are thread-safe. ### SEE ALSO **gettimeofday**(2), **clock_gettime**(2) libcpucycles-20260901/doc/counters.md0000644000000000000000000023365115245636444016116 0ustar rootrootCurrently libcpucycles supports the following cycle counters. Some cycle counters are actually other forms of counters that libcpucycles scales to imitate a cycle counter. There is [separate documentation](selection.html) for how libcpucycles makes a choice of cycle counter. There is a `cpucycles-open` command that, when run as `root`, often succeeds in enabling higher-quality cycle counters until reboot. See the [security considerations](security.html) regarding enabling or disabling counters and regarding overclocking (Turbo Boost, Turbo Core, etc.). `amd64-perfpmcff`: Requires a 64-bit Intel platform; the Linux `perf_event` interface; `/proc/sys/kernel/perf_event_paranoid` at most 2; any existing files among `/sys/devices/{cpu,cpu_core,cpu_atom}/rdpmc` at least 2. Accesses a cycle counter through RDPMC (using Intel-specific counter `0x40000001`, which is why this ends up not running on AMD CPUs). This counter runs at the clock frequency of the CPU core. Starting with libcpucycles version 20260625, this counter tries to compensate for a `perf_event` bug in handling Intel E-cores. Starting with libcpucycles version 20260901, the counter tries harder to compensate; also, this counter is skipped on cores with PMC version <3 or PMC width <48. `amd64-perfpmc`: Requires a 64-bit AMD platform; the Linux `perf_event` interface; `/proc/sys/kernel/perf_event_paranoid` at most 2; any existing files among `/sys/devices/{cpu,cpu_core,cpu_atom}/rdpmc` at least 2. Accesses a cycle counter through RDPMC (using the `perf_event` index); to avoid various `amd64-perfpmcff` complications, actively refuses to run on Intel. This counter runs at the clock frequency of the CPU core. `amd64-pmcff`: Requires a 64-bit Intel platform and an OS that enables user-level RDPMC access. Accesses a cycle counter through RDPMC (using Intel-specific counter `0x40000001`, which is why this ends up not running on AMD CPUs). This counter runs at the clock frequency of the CPU core. `amd64-tsc`, `amd64-tscasm`: Requires a 64-bit Intel/AMD platform. Requires RDTSC to be enabled, which it is by default. Uses RDTSC to access the CPU's time-stamp counter. On current CPUs, this is an off-core clock rather than a cycle counter, but it is typically a very fast off-core clock, making it adequate for seeing cycle counts if overclocking and underclocking are disabled. The difference between `tsc` and `tscasm` is that `tsc` uses the compiler's `__rdtsc()` while `tscasm` uses inline assembly. `arm32-cortex`: Requires a 32-bit ARMv7-A platform. Uses `mrc p15, 0, %0, c9, c13, 0` to read the cycle counter. Requires user access to the cycle counter, which is not enabled by default but can (sometimes) be enabled under Linux via [a kernel module](https://github.com/thoughtpolice/enable_arm_pmu). This counter is natively 32 bits, but libcpucycles watches how the counter and `gettimeofday` increase to compute a 64-bit extension of the counter. `arm32-1176`: Requires a 32-bit ARM1176 platform. Uses `mrc p15, 0, %0, c15, c12, 1` to read the cycle counter. Requires user access to the cycle counter, which is not enabled by default but can (sometimes) be enabled under Linux via [a kernel module](https://bench.cr.yp.to/cpucycles/n810.html). This counter is natively 32 bits, but libcpucycles watches how the counter and `gettimeofday` increase to compute a 64-bit extension of the counter. `arm64-perfpmc`: Requires a 64-bit ARMv8-A platform; the Linux `perf_event` interface; on current Linux kernels, 1 in `/proc/sys/kernel/perf_user_access`; on older Linux kernels, [a kernel module](https://github.com/rdolbeau/enable_arm_pmu) to enable PMCCNTR access. Uses `mrs %0, PMCCNTR_EL0` to read the cycle counter. `arm64-pmc`: Requires a 64-bit ARMv8-A platform and an OS that enables user-level PMCCNTR access, for example an older Linux kernel with [a kernel module](https://github.com/rdolbeau/enable_arm_pmu). Uses `mrs %0, PMCCNTR_EL0` to read the cycle counter. `arm64-vct`: Requires a 64-bit ARMv8-A platform. Uses `mrs %0, CNTVCT_EL0` to read a "virtual count" timer. This is an off-core clock, typically running at 24MHz. Results are scaled by libcpucycles. `loong64-rdtime`: Requires a 64-bit LoongArch platform. Uses `rdtime.d` to read the "constant frequency timer". This is an off-core clock, typically running at 100MHz. `mips64-cc`: Requires a 64-bit MIPS platform. (Maybe the same code would also work as `mips32-cc`, but this has not been tested yet.) Uses RDHWR to read the hardware cycle counter (hardware register 2 times a constant scale factor in hardware register 3). This counter is natively 32 bits, but libcpucycles watches how the counter and `gettimeofday` increase to compute a 64-bit extension of the counter. `ppc32-mftb`: Requires a 32-bit PowerPC platform. Uses `mftb` and `mftbu` to read the "time base". This is an off-core clock, typically running at 24MHz. `ppc64-mftb`: Requires a 64-bit PowerPC platform. Uses `mftb` and `mftbu` to read the "time base". This is an off-core clock, typically running at 24MHz. `riscv32-perfrdcycle`: Requires a 32-bit RISC-V platform; the Linux `perf_event` interface; on current Linux kernels, 1 in `/proc/sys/kernel/perf_user_access`. Uses `rdcycle` and `rdcycleh` to read a cycle counter. `riscv32-rdcycle`: Requires a 32-bit RISC-V platform and an OS that enables user-level `rdcycle` access. Uses `rdcycle` and `rdcycleh` to read a cycle counter. `riscv64-perfrdcycle`: Requires a 64-bit RISC-V platform; the Linux `perf_event` interface; on current Linux kernels, 1 in `/proc/sys/kernel/perf_user_access`. Uses `rdcycle` to read a cycle counter. `riscv64-rdcycle`: Requires a 64-bit RISC-V platform and an OS that enables user-level `rdcycle` access. Uses `rdcycle` to read a cycle counter. `s390x-stckf`: Requires a 64-bit z/Architecture platform. Uses `stckf` to read the TOD clock, which is documented to run at 4096MHz. On the z15, this looks like a doubling of an off-core 2048MHz clock. Results are scaled by libcpucycles. `sparc64-rdtick`: Requires a 64-bit SPARC platform. Uses `rd %tick` to read a cycle counter. `x86-tsc`, `x86-tscasm`: Same as `amd64-tsc` and `amd64-tscasm`, but for 32-bit Intel/AMD platforms instead of 64-bit Intel/AMD platforms. `default-gettimeofday`: Reasonably portable. Resolution is limited to 1 microsecond. Results are scaled by libcpucycles. `default-mach`: Requires an OS with `mach_absolute_time()`. Typically runs at 24MHz. Results are scaled by libcpucycles. `default-monotonic`: Requires `CLOCK_MONOTONIC`. Reasonably portable, although might fail on older systems where `default-gettimeofday` works. Resolution is limited to 1 nanosecond. Can be almost as good as a cycle counter, or orders of magnitude worse, depending on the OS and CPU. Results are scaled by libcpucycles. `default-perfevent`: Requires the Linux `perf_event` interface, and a CPU where `perf_event` supports `PERF_COUNT_HW_CPU_CYCLES`. Similar variations in quality to `default-monotonic`, without the 1-nanosecond limitation. Starting with libcpucycles version 20260625, this counter tries to compensate for a `perf_event` bug in handling Intel E-cores. Starting with libcpucycles version 20260901, the counter tries harder to compensate. `default-zero`: The horrifying last resort if nothing else works. ## Examples These are examples of `cpucycles-info` output on various machines. The machines named `cfarm*` are from the [cfarm compile farm](https://portal.cfarm.net/). A `median` line saying, e.g., `47 +47+28+0+2-5+0+2-5...` means that the differences between adjacent cycle counts were 47+47, 47+28, 47+0, 47+2, 47−5, 47+0, 47+2, 47−5, etc., with median difference 47. The first few differences are typically larger because of cache effects. Current versions of libcpucycles use `iqm` (interquartile mean) instead of `median`. `berry0`, Broadcom BCM2835: ``` cpucycles version 20240114 cpucycles tracesetup 0 arm32-cortex precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 arm32-1176 precision 22 scaling 1.000000 only32 1 cpucycles tracesetup 2 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 1199 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 1200 scaling 1000.000000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1000000000 cpucycles implementation arm32-1176 cpucycles median 720 +942+124+1+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+2+0+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+222+300+1+0+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 798307692...2045181819 with 1024 loops 12 microseconds cpucycles observed persecond 915478260...1260523810 with 2048 loops 22 microseconds cpucycles observed persecond 947809523...1106100000 with 4096 loops 41 microseconds cpucycles observed persecond 966353658...1129037500 with 8192 loops 81 microseconds cpucycles observed persecond 988490566...1030019109 with 16384 loops 158 microseconds cpucycles observed persecond 995169327...1002034063 with 32768 loops 2379 microseconds cpucycles observed persecond 996871019...1012568691 with 65536 loops 627 microseconds cpucycles observed persecond 997832134...1004212170 with 131072 loops 1250 microseconds cpucycles observed persecond 997740918...1000887780 with 262144 loops 5009 microseconds cpucycles observed persecond 998528349...1001961164 with 524288 loops 5537 microseconds cpucycles observed persecond 999202882...1001166794 with 1048576 loops 10547 microseconds ``` `berry2`, Broadcom BCM2836: ``` cpucycles version 20251226 cpucycles tracesetup 0 arm32-cortex precision 310 scaling 1.000000 only32 1 cpucycles tracesetup 1 arm32-1176 precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 254 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 814 scaling 0.900000 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 1200 scaling 900.000000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 900000000 cpucycles implementation default-perfevent cpucycles iqm 154 +208+9+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+173+172+29+0-4+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 218360000...420565218 with 1024 loops 24 microseconds cpucycles observed persecond 327781250...402566667 with 2048 loops 31 microseconds cpucycles observed persecond 423204081...468085107 with 4096 loops 48 microseconds cpucycles observed persecond 490369047...517231708 with 8192 loops 83 microseconds cpucycles observed persecond 544033112...560208054 with 16384 loops 150 microseconds cpucycles observed persecond 450227397...457187328 with 32768 loops 364 microseconds cpucycles observed persecond 584518716...588967800 with 65536 loops 560 microseconds cpucycles observed persecond 592214995...594508598 with 131072 loops 1106 microseconds cpucycles observed persecond 595894545...597049591 with 262144 loops 2199 microseconds cpucycles observed persecond 598008895...598558878 with 524288 loops 4383 microseconds cpucycles observed persecond 595624105...595918873 with 1048576 loops 8802 microseconds ``` `pi3aplus`, Broadcom BCM2837B0: ``` cpucycles version 20260625 cpucycles tracesetup 0 arm64-perfpmc precision 9 scaling 1.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1083 scaling 73.000000 only32 0 cpucycles tracesetup 3 default-perfevent precision 130 scaling 1.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1102 scaling 1.400000 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 2440 scaling 1400.000000 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1400000000 cpucycles implementation arm64-perfpmc cpucycles iqm 10 +15+8+8+3+0+0+0+0+0+0+0+7-2-2-2-1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 1030500000...2158500000 with 2048 loops 3 microseconds cpucycles observed persecond 1177285714...1688600000 with 4096 loops 6 microseconds cpucycles observed persecond 1369333333...1662000000 with 8192 loops 11 microseconds cpucycles observed persecond 1367000000...1499454546 with 16384 loops 23 microseconds cpucycles observed persecond 1366166666...1429565218 with 32768 loops 47 microseconds cpucycles observed persecond 1394808510...1427086957 with 65536 loops 93 microseconds cpucycles observed persecond 1165577777...1177856503 with 131072 loops 224 microseconds cpucycles observed persecond 1379878947...1387708995 with 262144 loops 379 microseconds cpucycles observed persecond 1390775862...1394730054 with 524288 loops 753 microseconds cpucycles observed persecond 1364528952...1366583714 with 1048576 loops 1536 microseconds ``` `pi4b`, Broadcom BCM2711, Ubuntu 24.04, Linux kernel 6.8.0-1036-raspi, running in power-saving mode (`echo powersave > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor`): ``` cpucycles version 20260901 cpucycles tracesetup 0 arm64-perfpmc precision 9 scaling 1.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1037 scaling 27.750000 only32 0 cpucycles tracesetup 3 default-perfevent precision 179 scaling 1.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1252 scaling 1.500000 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 2540 scaling 1500.000000 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1500000000 cpucycles implementation arm64-perfpmc cpucycles iqm 9 +40+1+0+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 423800000...803333334 with 1024 loops 4 microseconds cpucycles observed persecond 520875000...729000000 with 2048 loops 7 microseconds cpucycles observed persecond 550866666...649076924 with 4096 loops 14 microseconds cpucycles observed persecond 587678571...640961539 with 8192 loops 27 microseconds cpucycles observed persecond 586410714...611962963 with 16384 loops 55 microseconds cpucycles observed persecond 596427272...609388889 with 32768 loops 109 microseconds cpucycles observed persecond 596104545...602522936 with 65536 loops 219 microseconds cpucycles observed persecond 560482905...563418455 with 131072 loops 467 microseconds cpucycles observed persecond 581430155...582961112 with 262144 loops 901 microseconds cpucycles observed persecond 587575350...588363433 with 524288 loops 1784 microseconds cpucycles observed persecond 590009001...590410639 with 1048576 loops 3554 microseconds ``` `pi5`, Broadcom BCM2712, Debian 12, Linux kernel 6.12.25+rpt-rpi-2712, running in power-saving mode (`echo powersave > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor`): ``` cpucycles version 20260625 cpucycles tracesetup 0 arm64-perfpmc precision 2 scaling 1.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1054 scaling 44.500000 only32 0 cpucycles tracesetup 3 default-perfevent precision 97 scaling 1.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1162 scaling 2.400000 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 3440 scaling 2400.000000 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2400000000 cpucycles implementation arm64-perfpmc cpucycles iqm 7 +11+12+1+12+1+12+1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+3-3+2+1-3+2-2+0+0+0+0+0+3-3+2-2+0+0+0+0+3-3+2-2+0+0+0+0+3-3+2-2+0+0+0+0+0+0+0 cpucycles observed persecond 1034000000...2137000000 with 4096 loops 3 microseconds cpucycles observed persecond 1178428571...1673800000 with 8192 loops 6 microseconds cpucycles observed persecond 1370416666...1656500000 with 16384 loops 11 microseconds cpucycles observed persecond 1426434782...1568000000 with 32768 loops 22 microseconds cpucycles observed persecond 1457222222...1527790698 with 65536 loops 44 microseconds cpucycles observed persecond 1489897727...1525930233 with 131072 loops 87 microseconds cpucycles observed persecond 1489687500...1507494253 with 262144 loops 175 microseconds cpucycles observed persecond 1493823361...1502727794 with 524288 loops 350 microseconds cpucycles observed persecond 1495885877...1500337626 with 1048576 loops 700 microseconds ``` `bblack`, TI Sitara XAM3359AZCZ100: ``` cpucycles version 20260625 cpucycles tracesetup 0 arm32-cortex precision 308 scaling 1.000000 only32 1 cpucycles tracesetup 1 arm32-1176 precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 2134 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 2020 scaling 1000.000000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1000000000 cpucycles implementation arm32-cortex cpucycles iqm 1260 +166+5+19+0+10+0+0+0+0+0+0+0+0+0+0+0+0+10+0+0+0+2+8+0+0+0+0+0+0+2+8+2+8+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+12+8+0+0+10+0+0+0+0+10+0+2+8+0+0 cpucycles observed persecond 625636363...5378111112 with 1024 loops 10 microseconds cpucycles observed persecond 768600000...1400692308 with 2048 loops 14 microseconds cpucycles observed persecond 869240000...1162217392 with 4096 loops 24 microseconds cpucycles observed persecond 938333333...1097976745 with 8192 loops 44 microseconds cpucycles observed persecond 956057471...1037282353 with 16384 loops 86 microseconds cpucycles observed persecond 977035502...1018814372 with 32768 loops 168 microseconds cpucycles observed persecond 987789789...1008755288 with 65536 loops 332 microseconds cpucycles observed persecond 994892424...1005542554 with 131072 loops 659 microseconds cpucycles observed persecond 997695057...1002990861 with 262144 loops 1314 microseconds cpucycles observed persecond 998862529...1000671667 with 524288 loops 6735 microseconds cpucycles observed persecond 999072352...1000502726 with 1048576 loops 9356 microseconds ``` `titan0`, Intel Xeon E3-1275 V3: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 37 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1034 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1044 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 114 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1106 scaling 3.500000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 4550 scaling 3500.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3500000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 41 +40+40+20+20-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0 cpucycles observed persecond 2751166666...4174000000 with 16384 loops 5 microseconds cpucycles observed persecond 3285200000...4136000000 with 32768 loops 9 microseconds cpucycles observed persecond 3177258064...3406413794 with 65536 loops 30 microseconds cpucycles observed persecond 3294750000...3473105264 with 131072 loops 39 microseconds cpucycles observed persecond 3405415584...3498733334 with 262144 loops 76 microseconds cpucycles observed persecond 3472529801...3520382551 with 524288 loops 150 microseconds cpucycles observed persecond 3472317880...3496096667 with 1048576 loops 301 microseconds ``` `wolfdale`, Intel Core 2 Duo E7600: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1069 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1079 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 255 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 5921 scaling 3.059000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 4099 scaling 3059.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3059000000 cpucycles implementation default-perfevent cpucycles iqm 242 +0+0+0+0+0+4+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 345142857...1156200000 with 1024 loops 6 microseconds cpucycles observed persecond 551000000...927166667 with 2048 loops 7 microseconds cpucycles observed persecond 847800000...1201125000 with 4096 loops 9 microseconds cpucycles observed persecond 1041875000...1272428572 with 8192 loops 15 microseconds cpucycles observed persecond 1271307692...1424875000 with 16384 loops 25 microseconds cpucycles observed persecond 1255358490...1328470589 with 32768 loops 52 microseconds cpucycles observed persecond 1492704545...1540976745 with 65536 loops 87 microseconds cpucycles observed persecond 1543705882...1568791667 with 131072 loops 169 microseconds cpucycles observed persecond 1565892537...1578696697 with 262144 loops 334 microseconds cpucycles observed persecond 1579611445...1586093656 with 524288 loops 663 microseconds cpucycles observed persecond 1585365079...1588622256 with 1048576 loops 1322 microseconds ``` `nucnuc`, Intel Pentium N3700 (Airmont, 40-bit PMC): ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1020 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1030 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 386 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1150 scaling 1.600000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2640 scaling 1600.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1600000000 cpucycles implementation default-perfevent cpucycles iqm 506 -5-3-19+0+0+0+0+0+0+0+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 462166666...2148500000 with 1024 loops 5 microseconds cpucycles observed persecond 666714285...1241400000 with 2048 loops 6 microseconds cpucycles observed persecond 874600000...1281625000 with 4096 loops 9 microseconds cpucycles observed persecond 1135866666...1425846154 with 8192 loops 14 microseconds cpucycles observed persecond 1332840000...1513869566 with 16384 loops 24 microseconds cpucycles observed persecond 1436847826...1536227273 with 32768 loops 45 microseconds cpucycles observed persecond 1514149425...1567435295 with 65536 loops 86 microseconds cpucycles observed persecond 1554414201...1582000000 with 131072 loops 168 microseconds cpucycles observed persecond 1580843373...1594954546 with 262144 loops 331 microseconds cpucycles observed persecond 1536684133...1547656935 with 524288 loops 686 microseconds cpucycles observed persecond 1594012917...1597585236 with 1048576 loops 1315 microseconds ``` `gemini`, Intel Celeron N4020 (Goldmont, 48-bit PMC): ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1033 scaling 1.005117 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1040 scaling 1.005117 only32 0 cpucycles tracesetup 5 default-perfevent precision 135 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1118 scaling 1.100000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2150 scaling 1100.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1100000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 17 +11+11+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1 cpucycles observed persecond 835000000...2161666667 with 1024 loops 4 microseconds cpucycles observed persecond 919555555...1244428572 with 2048 loops 8 microseconds cpucycles observed persecond 1027750000...1205642858 with 4096 loops 15 microseconds cpucycles observed persecond 1058967741...1147000000 with 8192 loops 30 microseconds cpucycles observed persecond 1075344262...1119169492 with 16384 loops 60 microseconds cpucycles observed persecond 1083735537...1105605043 with 32768 loops 120 microseconds cpucycles observed persecond 1087983402...1098907950 with 65536 loops 240 microseconds cpucycles observed persecond 1094672233...1100044026 with 131072 loops 478 microseconds cpucycles observed persecond 1095753396...1098503665 with 262144 loops 956 microseconds cpucycles observed persecond 1096294824...1097637363 with 524288 loops 1912 microseconds cpucycles observed persecond 1091311134...1092790995 with 1048576 loops 3843 microseconds ``` `saber214`, AMD FX-8350, running under Xen: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1071 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1080 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1188 scaling 4.013514 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 5043 scaling 4013.514000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 4013514000 cpucycles implementation amd64-tsc cpucycles iqm 72 +44-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0+0+0-1+0-1+1-1+0-1+0+0 cpucycles observed persecond 3018000000...6236500000 with 4096 loops 3 microseconds cpucycles observed persecond 3438000000...4895800000 with 8192 loops 6 microseconds cpucycles observed persecond 3695615384...4404090910 with 16384 loops 12 microseconds cpucycles observed persecond 4001083333...4382909091 with 32768 loops 23 microseconds cpucycles observed persecond 3916714285...4091872341 with 65536 loops 48 microseconds cpucycles observed persecond 3997031250...4086319149 with 131072 loops 95 microseconds cpucycles observed persecond 3996567708...4040752632 with 262144 loops 191 microseconds cpucycles observed persecond 4005274271...4025941464 with 524288 loops 411 microseconds cpucycles observed persecond 4006639686...4017687173 with 1048576 loops 765 microseconds ``` `phoenix`, AMD Ryzen 5 7640HS: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 34 scaling 1.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1011 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1021 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 176 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1126 scaling 4.301000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 5351 scaling 4301.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 4301000000 cpucycles implementation amd64-perfpmc cpucycles iqm 34 +35+0+0+0+0+0+0+471+0+0+0+0+0+0+0+0+0+0+0+459-1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 3289200000...5535333334 with 16384 loops 4 microseconds cpucycles observed persecond 3647777777...4715285715 with 32768 loops 8 microseconds cpucycles observed persecond 3858705882...4383866667 with 65536 loops 16 microseconds cpucycles observed persecond 4097937500...4376466667 with 131072 loops 31 microseconds cpucycles observed persecond 4162000000...4301081968 with 262144 loops 62 microseconds cpucycles observed persecond 4228629032...4299262296 with 524288 loops 123 microseconds cpucycles observed persecond 4228379032...4263406505 with 1048576 loops 247 microseconds ``` `alder2`, Intel Core i3-1215U, P-core: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 8 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1045 scaling 0.480769 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1055 scaling 0.480769 only32 0 cpucycles tracesetup 5 default-perfevent precision 108 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1137 scaling 1.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 11 +57+37+32+7+2+4+2+2+1+0-1+0-1+1+1+0+0+1-3+2-2+2-2+3-2+1+1+0-2+1-1+2-3+3-1+1-3+3-1+0-1+1-1+2-2+2-3+2-2+2-2+1-1+3+0-1+1-2+2-2+0+0+2-1 cpucycles observed persecond 556400000...966333334 with 4096 loops 4 microseconds cpucycles observed persecond 698250000...955666667 with 8192 loops 7 microseconds cpucycles observed persecond 735533333...857769231 with 16384 loops 14 microseconds cpucycles observed persecond 784107142...848961539 with 32768 loops 27 microseconds cpucycles observed persecond 782250000...813518519 with 65536 loops 55 microseconds cpucycles observed persecond 795663636...811490741 with 131072 loops 109 microseconds cpucycles observed persecond 795159090...802986239 with 262144 loops 219 microseconds cpucycles observed persecond 796719817...800631579 with 524288 loops 438 microseconds cpucycles observed persecond 960726648...963537191 with 1048576 loops 727 microseconds ``` `alder2`, Intel Core i3-1215U, E-core: ``` cpucycles version 20260901 cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1055 scaling 0.480769 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1065 scaling 0.480769 only32 0 cpucycles tracesetup 5 default-perfevent precision 122 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1139 scaling 1.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 17 +11+1-1+1-1+1-1+1-1+1-1+1+3-3-1+1-1+1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+3-1-1-1+3-3+3-3+1-1+2-1-1+2-1-1+1-1+1-1+1-1+1-1+1-1+3-3+2-1-1+1 cpucycles observed persecond 835200000...1431666667 with 2048 loops 4 microseconds cpucycles observed persecond 769545454...955555556 with 4096 loops 10 microseconds cpucycles observed persecond 829900000...929555556 with 8192 loops 19 microseconds cpucycles observed persecond 860500000...909342106 with 16384 loops 39 microseconds cpucycles observed persecond 892932432...919611112 with 32768 loops 73 microseconds cpucycles observed persecond 893517006...906758621 with 65536 loops 146 microseconds cpucycles observed persecond 895385665...902000000 with 131072 loops 292 microseconds cpucycles observed persecond 896545299...899850772 with 262144 loops 584 microseconds cpucycles observed persecond 897159110...898811483 with 524288 loops 1168 microseconds cpucycles observed persecond 892638605...893458298 with 1048576 loops 2351 microseconds ``` `freshwrap`, Intel Core 5 210H, P-core: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1049 scaling 0.818452 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1059 scaling 0.818452 only32 0 cpucycles tracesetup 5 default-perfevent precision 142 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1103 scaling 2.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 3250 scaling 2200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 14 +55+27-3-1+0+3-1+1+0+3+5-3+5-1+5-2+3-1+2-1+0+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0 cpucycles observed persecond 1828333333...2773500000 with 16384 loops 5 microseconds cpucycles observed persecond 1991818181...2450777778 with 32768 loops 10 microseconds cpucycles observed persecond 2082761904...2308368422 with 65536 loops 20 microseconds cpucycles observed persecond 2132878048...2245358975 with 131072 loops 40 microseconds cpucycles observed persecond 2165755813...2218761905 with 262144 loops 85 microseconds cpucycles observed persecond 2185543750...2213962026 with 524288 loops 159 microseconds cpucycles observed persecond 2189342679...2203442007 with 1048576 loops 320 microseconds ``` `freshwrap`, Intel Core 5 210H, E-core: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1049 scaling 0.818452 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1059 scaling 0.818452 only32 0 cpucycles tracesetup 5 default-perfevent precision 121 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1143 scaling 2.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 3250 scaling 2200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 17 +21+22+1+3-3+1-1+2-1-1+1-1+3-3+1-1+3-1-1-1+1-1+1-1+1-1+1-1+2-1-1+2-1-1+1-1+1-1+1-1+1-1+1-1+3-3+2-1-1+1-1+3-3+2-1-1+1-1+1-1+2-1-1+1 cpucycles observed persecond 1060750000...2189000000 with 4096 loops 3 microseconds cpucycles observed persecond 1275571428...1819800000 with 8192 loops 6 microseconds cpucycles observed persecond 1475250000...1787300000 with 16384 loops 11 microseconds cpucycles observed persecond 1525217391...1678571429 with 32768 loops 22 microseconds cpucycles observed persecond 1541955555...1617651163 with 65536 loops 44 microseconds cpucycles observed persecond 1575720930...1615285715 with 131072 loops 85 microseconds cpucycles observed persecond 1581636904...1601716868 with 262144 loops 167 microseconds cpucycles observed persecond 1593329305...1603534955 with 524288 loops 330 microseconds cpucycles observed persecond 1595613050...1600729072 with 1048576 loops 658 microseconds ``` `meteor`, Intel Core Ultra 5 125H, P-core: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 8 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1033 scaling 0.400641 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1043 scaling 0.400641 only32 0 cpucycles tracesetup 5 default-perfevent precision 143 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1104 scaling 1.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 20 +55+25+0+3-4+3+2+9-7-3-3-3-4+0-2+0-4-1-3-3-4-1-1-6-3-3+2+1+6-2-1+10-12+6+2+4-9+2+0-1-1+40-7+3+0+2+0+4-4-1-6-3-3-6+4+3+5-4+12+1+8+10+12+5 cpucycles observed persecond 938750000...1949000000 with 4096 loops 3 microseconds cpucycles observed persecond 1055500000...1458500000 with 8192 loops 7 microseconds cpucycles observed persecond 1057875000...1219928572 with 16384 loops 15 microseconds cpucycles observed persecond 1176060606...1258387097 with 32768 loops 32 microseconds cpucycles observed persecond 1169929824...1215672728 with 65536 loops 56 microseconds cpucycles observed persecond 1190088888...1218943182 with 131072 loops 89 microseconds cpucycles observed persecond 1189457317...1205123457 with 262144 loops 163 microseconds cpucycles observed persecond 1193379870...1201712419 with 524288 loops 307 microseconds cpucycles observed persecond 1196813021...1201098828 with 1048576 loops 598 microseconds ``` `meteor`, Intel Core Ultra 5 125H, E-core: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1059 scaling 0.400641 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1068 scaling 0.400641 only32 0 cpucycles tracesetup 5 default-perfevent precision 124 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1167 scaling 1.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1200000000 cpucycles implementation amd64-perfpmcff cpucycles iqm 17 +1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+1-1+2-1-1+1-1+3-3+1-1+1-1+1-1+2-1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+2-1-1+1-1+2-1-1+1-1+1-1+1-1+1-1+1-1 cpucycles observed persecond 439200000...770666667 with 2048 loops 4 microseconds cpucycles observed persecond 608857142...878200000 with 4096 loops 6 microseconds cpucycles observed persecond 638000000...764363637 with 8192 loops 12 microseconds cpucycles observed persecond 687750000...756136364 with 16384 loops 23 microseconds cpucycles observed persecond 670959183...701978724 with 32768 loops 48 microseconds cpucycles observed persecond 691105263...707182796 with 65536 loops 94 microseconds cpucycles observed persecond 694132275...702160428 with 131072 loops 188 microseconds cpucycles observed persecond 667098984...671061225 with 262144 loops 393 microseconds cpucycles observed persecond 697416223...699448000 with 524288 loops 751 microseconds cpucycles observed persecond 697739188...698754164 with 1048576 loops 1502 microseconds ``` `cfarm14`, Intel Xeon E5-2620 v3, Debian 12, Linux kernel 6.1.0-26-amd64: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1018 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1028 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 84 scaling 1.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1110 scaling 3.200000 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 4240 scaling 3200.000000 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3200000000 cpucycles implementation default-perfevent cpucycles iqm 74 +50+0+0+0+0+0+0+0+0-2+1+0+2+0+0+0+1+0+0+0+0+0+0-2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+0+1+1+0-2+0+0+2+0-2-2-2 cpucycles observed persecond 541000000...1232500000 with 2048 loops 3 microseconds cpucycles observed persecond 1053750000...2229000000 with 4096 loops 3 microseconds cpucycles observed persecond 1385500000...2138750000 with 8192 loops 5 microseconds cpucycles observed persecond 1833555555...2392857143 with 16384 loops 8 microseconds cpucycles observed persecond 2192533333...2549230770 with 32768 loops 14 microseconds cpucycles observed persecond 2344750000...2534730770 with 65536 loops 27 microseconds cpucycles observed persecond 2475471698...2577333334 with 131072 loops 52 microseconds cpucycles observed persecond 2522778846...2574598040 with 262144 loops 103 microseconds cpucycles observed persecond 2507608832...2525190477 with 524288 loops 316 microseconds cpucycles observed persecond 2583098522...2596502476 with 1048576 loops 405 microseconds ``` `cfarm26`, Intel Core i5-4570 in 32-bit mode under KVM, Debian 12.12, Linux kernel 6.1.0-41-686-pae: ``` cpucycles version 20260625 cpucycles tracesetup 0 x86-tsc precision 1018 scaling 1.000000 only32 0 cpucycles tracesetup 1 x86-tscasm precision 1028 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 731 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 3220 scaling 3.192606 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 4232 scaling 3192.606000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3192606000 cpucycles implementation default-perfevent cpucycles iqm 779 +35-8+9+15+10-3-7-8-15+10+0-8+4+3-1-1+11+11-1+6+4-3-15-7+3-3+0-7+5+3-8+10+4+3+0-15-3-3-1-14-3+3+10-1-3-3-1-7+3-4+0+0-10+3-8+0+4-1+0-7+4+3-8+0 cpucycles observed persecond 283428571...1430400000 with 1024 loops 6 microseconds cpucycles observed persecond 417142857...1240800000 with 2048 loops 6 microseconds cpucycles observed persecond 715571428...1662000000 with 4096 loops 6 microseconds cpucycles observed persecond 1132500000...2059666667 with 8192 loops 7 microseconds cpucycles observed persecond 1568000000...2281333334 with 16384 loops 10 microseconds cpucycles observed persecond 2254933333...2854769231 with 32768 loops 14 microseconds cpucycles observed persecond 2658360000...3034000000 with 65536 loops 24 microseconds cpucycles observed persecond 2174032786...2310118645 with 131072 loops 60 microseconds cpucycles observed persecond 3329126582...3459415585 with 262144 loops 78 microseconds cpucycles observed persecond 3455059210...3523140000 with 524288 loops 151 microseconds cpucycles observed persecond 3454417763...3489394040 with 1048576 loops 303 microseconds ``` `cfarm27`, Intel Core i5-4570 in 32-bit mode under KVM, Alpine 3.19.9, Linux kernel 6.6.117-0-lts: ``` cpucycles version 20260625 cpucycles tracesetup 0 x86-tsc precision 1018 scaling 1.000000 only32 0 cpucycles tracesetup 1 x86-tscasm precision 1028 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 608 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 1601 scaling 3.192606 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 4232 scaling 3192.606000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3192606000 cpucycles implementation default-perfevent cpucycles iqm 606 +72+2-9-3+2+6-4-2+2+2-6-3+5+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2 cpucycles observed persecond 356800000...1256666667 with 1024 loops 4 microseconds cpucycles observed persecond 537400000...1404666667 with 2048 loops 4 microseconds cpucycles observed persecond 787166666...1562500000 with 4096 loops 5 microseconds cpucycles observed persecond 1261142857...2072000000 with 8192 loops 6 microseconds cpucycles observed persecond 1890444444...2648714286 with 16384 loops 8 microseconds cpucycles observed persecond 2392285714...2934250000 with 32768 loops 13 microseconds cpucycles observed persecond 2879304347...3228952381 with 65536 loops 22 microseconds cpucycles observed persecond 2723040816...2872978724 with 131072 loops 48 microseconds cpucycles observed persecond 3326113924...3432428572 with 262144 loops 78 microseconds cpucycles observed persecond 3386496774...3440797386 with 524288 loops 154 microseconds cpucycles observed persecond 3202069696...3226439025 with 1048576 loops 329 microseconds ``` `cfarm29`, IBM POWER9, Debian 13.1, Linux kernel 6.12.57+deb13-powerpc64le: ``` cpucycles version 20260105 cpucycles tracesetup 0 ppc64-mftb precision 220 scaling 7.500000 only32 0 cpucycles tracesetup 1 default-perfevent precision 367 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 419 scaling 3.800000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 4130 scaling 3800.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3800000000 cpucycles implementation ppc64-mftb cpucycles iqm 131 +26+27-4-3+4-4+4-3+4-4-3+11-3+4-4-3+4-4+4-3+4-4+4-3+4-4+4+4-3-4+4-3+4+11-3-11+4-4+4-3+4-4-3-4+12-4+4-3+4-11+4-4+4-3-4+12+4-11+4-4-3+4-4-3 cpucycles observed persecond 2535000000...5449000000 with 2048 loops 3 microseconds cpucycles observed persecond 3042000000...5350000000 with 4096 loops 4 microseconds cpucycles observed persecond 3244222222...4275000000 with 8192 loops 8 microseconds cpucycles observed persecond 3587533333...4187846154 with 16384 loops 14 microseconds cpucycles observed persecond 3714333333...3981290323 with 32768 loops 32 microseconds cpucycles observed persecond 3693138888...3924264706 with 65536 loops 35 microseconds cpucycles observed persecond 3795971428...3913897059 with 131072 loops 69 microseconds cpucycles observed persecond 3821978417...3880839417 with 262144 loops 138 microseconds cpucycles observed persecond 3821845323...3851086957 with 524288 loops 277 microseconds cpucycles observed persecond 3835166064...3849797102 with 1048576 loops 553 microseconds ``` `cfarm45`, AMD Athlon II X4 640, Debian 8.11, Linux kernel 3.16.0-11-686-pae: ``` cpucycles version 20230105 cpucycles tracesetup 0 x86-tsc precision 199 scaling 1.000000 only32 0 cpucycles tracesetup 1 x86-tscasm precision 199 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 170 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 941 scaling 3.000000 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 3200 scaling 3000.000000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3000000000 cpucycles implementation default-perfevent cpucycles median 72 +12+0+0+0+0+0+0+0+5+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0 cpucycles observed persecond 541500000...1812000000 with 1024 loops 3 microseconds cpucycles observed persecond 712333333...1212250000 with 2048 loops 5 microseconds cpucycles observed persecond 1193285714...1733600000 with 4096 loops 6 microseconds cpucycles observed persecond 1689176470...1804562500 with 8192 loops 33 microseconds cpucycles observed persecond 1713074626...1770600000 with 16384 loops 66 microseconds cpucycles observed persecond 1765107692...1795140625 with 32768 loops 129 microseconds cpucycles observed persecond 1785369649...1800603922 with 65536 loops 256 microseconds cpucycles observed persecond 1781377862...1796288462 with 131072 loops 261 microseconds cpucycles observed persecond 1772647398...1778247827 with 262144 loops 691 microseconds cpucycles observed persecond 1789670493...1794149598 with 524288 loops 870 microseconds cpucycles observed persecond 1860276211...1861561332 with 1048576 loops 3156 microseconds ``` `cfarm91`, StarFive JH7100, Debian trixie/sid, Linux kernel 5.18.11-starfive: ``` cpucycles version 20250925 cpucycles tracesetup 0 riscv64-rdcycle precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 2702 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 1351 scaling 2.399988 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 2599 scaling 2399.987654 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation default-monotonic cpucycles iqm 1476 +828-324+60+60+60+60-324+60-324+60+60-324+60+60-324+60+60-324+60-324+60+60-324+62-324+60+60-324+60+60-324+60-324+60+60-324+60+60-324+60-324+60+60-324+60+60-324+60-324+60+60+60+60+60-324+60-324+62+60+444+60-324+60+60 cpucycles observed persecond 1440250000...3968333334 with 1024 loops 7 microseconds cpucycles observed persecond 1920181818...3072222223 with 2048 loops 10 microseconds cpucycles observed persecond 2162473684...2733294118 with 4096 loops 18 microseconds cpucycles observed persecond 2218777777...2530000000 with 8192 loops 35 microseconds cpucycles observed persecond 2338014705...2490318182 with 16384 loops 67 microseconds cpucycles observed persecond 2358559701...2440840910 with 32768 loops 133 microseconds cpucycles observed persecond 2380905660...2419452472 with 65536 loops 264 microseconds cpucycles observed persecond 2390815939...2410163810 with 131072 loops 526 microseconds cpucycles observed persecond 2393901140...2403580953 with 262144 loops 1051 microseconds cpucycles observed persecond 2397546190...2402577217 with 524288 loops 2099 microseconds cpucycles observed persecond 2398864140...2401570967 with 1048576 loops 4327 microseconds ``` `cfarm92`, SiFive Freedom U740, Ubuntu 22.04.3, Linux kernel 5.19.0-1021-generic: ``` cpucycles version 20240114 cpucycles tracesetup 0 riscv64-rdcycle precision 8 scaling 1.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 2599 scaling 2.399988 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 2599 scaling 2399.987654 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation riscv64-rdcycle cpucycles median 8 +168+20+2+2+0+0+0+0+570+0+0+0+0+0+0+0+144+0+0+0+0+0+0+0+160+0+0+0+0+0+0+0+160+0+0+0+0+0+0+0+154+0+0+0+0+0+0+0+154+0+0+0+0+0+0+0+152+0+0+0+0+0+0 cpucycles observed persecond 571500000...2198000000 with 1024 loops 3 microseconds cpucycles observed persecond 833600000...2094000000 with 2048 loops 4 microseconds cpucycles observed persecond 921888888...1445142858 with 4096 loops 8 microseconds cpucycles observed persecond 1029625000...1320642858 with 8192 loops 15 microseconds cpucycles observed persecond 1137034482...1284481482 with 16384 loops 28 microseconds cpucycles observed persecond 1155701754...1227454546 with 32768 loops 56 microseconds cpucycles observed persecond 1177464285...1217163637 with 65536 loops 111 microseconds cpucycles observed persecond 1188018099...1207858448 with 131072 loops 220 microseconds cpucycles observed persecond 1189925170...1200519363 with 262144 loops 440 microseconds cpucycles observed persecond 1193962457...1199117446 with 524288 loops 878 microseconds cpucycles observed persecond 1194051324...1196780111 with 1048576 loops 1811 microseconds ``` `cfarm94`, SiFive StarFive JH7110, Alpine 3.22.0_alpha20250108, Linux kernel 6.12.19-2-lts: ``` cpucycles version 20260625 cpucycles tracesetup 0 riscv64-perfrdcycle precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 riscv64-rdcycle precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 0 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 1750 scaling 1.500000 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 2510 scaling 1500.000000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1500000000 cpucycles implementation default-monotonic cpucycles iqm 1125 +0+0+0-375+0+0+0+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+1-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0-375+0 cpucycles observed persecond 600000000...2500000000 with 1024 loops 4 microseconds cpucycles observed persecond 875000000...2343750000 with 2048 loops 5 microseconds cpucycles observed persecond 1083444444...1982285715 with 4096 loops 8 microseconds cpucycles observed persecond 1258928571...1812500000 with 8192 loops 13 microseconds cpucycles observed persecond 1312576923...1609458334 with 16384 loops 25 microseconds cpucycles observed persecond 1412255319...1583355556 with 32768 loops 46 microseconds cpucycles observed persecond 1451762376...1526545455 with 65536 loops 100 microseconds cpucycles observed persecond 1487322033...1527891429 with 131072 loops 176 microseconds cpucycles observed persecond 1490735537...1511465374 with 262144 loops 362 microseconds cpucycles observed persecond 1493099573...1503243938 with 524288 loops 702 microseconds cpucycles observed persecond 1497124823...1502417373 with 1048576 loops 1417 microseconds ``` `cfarm95`, SpacemiT X60, Debian trixie/sid, Linux kernel 6.6.36-cfarm #1: ``` cpucycles version 20260625 cpucycles tracesetup 0 riscv64-perfrdcycle precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 riscv64-rdcycle precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-perfevent precision 1794 scaling 1.000000 only32 0 cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-monotonic precision 1111 scaling 1.228800 only32 0 cpucycles tracesetup 5 default-gettimeofday precision 2248 scaling 1228.800000 only32 0 cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 1228800000 cpucycles implementation default-monotonic cpucycles iqm 135 -33+19-32+172+19-33+18-33+19+19-32+888+19-33+19-32+18-33+19+224-33+18-33+19-32+19-33+377-33+19-33+18-31+18-33+428-32+19-33+18-33+19-32+633+19-33+18-33+19-32+19+376+18-31+18-33+19-33+18+19+19-32+19-33 cpucycles observed persecond 468000000...6052000000 with 1024 loops 6 microseconds cpucycles observed persecond 962800000...2696333334 with 2048 loops 4 microseconds cpucycles observed persecond 1043250000...1476166667 with 4096 loops 7 microseconds cpucycles observed persecond 1102600000...1311461539 with 8192 loops 14 microseconds cpucycles observed persecond 1175785714...1285923077 with 16384 loops 27 microseconds cpucycles observed persecond 1198090909...1253943397 with 32768 loops 54 microseconds cpucycles observed persecond 1214266055...1246056075 with 65536 loops 108 microseconds cpucycles observed persecond 1217488479...1237860466 with 131072 loops 216 microseconds cpucycles observed persecond 1224293023...1233245328 with 262144 loops 429 microseconds cpucycles observed persecond 1225245348...1230967366 with 524288 loops 859 microseconds cpucycles observed persecond 1227769590...1230615926 with 1048576 loops 1709 microseconds ``` `cfarm103`, Apple M1 (Icestorm-M1 + Firestorm-M1), Debian trixie/sid, Linux kernel 6.5.0-asahi-00780-g62806c2c6f29: ``` cpucycles version 20260625 cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1086 scaling 86.000000 only32 0 cpucycles tracesetup 3 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1094 scaling 2.064000 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 3084 scaling 2064.000000 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2064000000 cpucycles implementation arm64-vct cpucycles iqm 0 +0+0+0+86+0+0+0+0+258+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+86+0+0+0 cpucycles observed persecond 1311500000...2709000000 with 4096 loops 3 microseconds cpucycles observed persecond 1748666666...2666000000 with 8192 loops 5 microseconds cpucycles observed persecond 1834666666...2383428572 with 16384 loops 8 microseconds cpucycles observed persecond 2053250000...2358857143 with 32768 loops 15 microseconds cpucycles observed persecond 1988424242...2122258065 with 65536 loops 32 microseconds cpucycles observed persecond 2017692307...2084476191 with 131072 loops 64 microseconds cpucycles observed persecond 2050129032...2078052288 with 262144 loops 154 microseconds cpucycles observed persecond 2056833333...2071818182 with 524288 loops 287 microseconds cpucycles observed persecond 2060477815...2067828768 with 1048576 loops 585 microseconds ``` `cfarm104`, Apple M1 (Icestorm-M1 + Firestorm-M1), MacOSX 12.6 21.6.0: ``` cpucycles version 20251226 cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 200 scaling 100.000000 only32 0 cpucycles tracesetup 3 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 4 default-mach precision 200 scaling 100.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 2699 scaling 2.399988 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 2699 scaling 2399.987654 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation arm64-vct cpucycles iqm 0 +4500+0+0+0+0+0+100+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+100+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+100+0+0+0+0+0+0+0 cpucycles observed persecond 1725000000...3450000000 with 8192 loops 3 microseconds cpucycles observed persecond 1885714285...2640000000 with 16384 loops 6 microseconds cpucycles observed persecond 2300000000...2533333334 with 32768 loops 22 microseconds cpucycles observed persecond 2339285714...2523076924 with 65536 loops 27 microseconds cpucycles observed persecond 2348529411...2421212122 with 131072 loops 67 microseconds cpucycles observed persecond 2377678571...2420909091 with 262144 loops 111 microseconds cpucycles observed persecond 2387214611...2410138249 with 524288 loops 218 microseconds cpucycles observed persecond 2397814207...2411813187 with 1048576 loops 365 microseconds ``` `cfarm110` (`gcc1-power7`), IBM POWER7, CentOS 7.9 AltArch, Linux kernel 3.10.0-1160.105.1.el7.ppc64: ``` cpucycles version 20260105 cpucycles tracesetup 0 ppc64-mftb precision 212 scaling 7.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 236 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 465 scaling 3.550000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 3880 scaling 3550.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3550000000 cpucycles implementation ppc64-mftb cpucycles iqm 167 +36-34+36-34-13+15-20+22-27+29-41+43-48+36-41+36-34+22-20+15-13+8-6-6+8-13+15-20+22-34+36+15-13+8-6+1+1-13+15-20+22-34+36-48+36-41+8-6+36-34+22-20+15-13+8-6-6+8-20+22-27+29-41+36 cpucycles observed persecond 3159333333...4905250000 with 4096 loops 5 microseconds cpucycles observed persecond 3386727272...4216333334 with 8192 loops 10 microseconds cpucycles observed persecond 3348333333...3739842106 with 16384 loops 20 microseconds cpucycles observed persecond 3534829268...3733153847 with 32768 loops 40 microseconds cpucycles observed persecond 3473016129...3599166667 with 65536 loops 61 microseconds cpucycles observed persecond 3541000000...3609900000 with 131072 loops 111 microseconds cpucycles observed persecond 3571450450...3606177273 with 262144 loops 221 microseconds cpucycles observed persecond 3578959367...3596333334 with 524288 loops 442 microseconds cpucycles observed persecond 3578793453...3587492082 with 1048576 loops 885 microseconds ``` `cfarm112` (`gcc2-power8`), IBM POWER8E, CentOS 7.9 AltArch, Linux kernel 3.10.0-1127.13.1.el7.ppc64le: ``` cpucycles version 20260625 cpucycles tracesetup 0 ppc64-mftb precision 1159 scaling 7.250000 only32 0 cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 1342 scaling 3.690000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 4710 scaling 3690.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3690000000 cpucycles implementation ppc64-mftb cpucycles iqm 194 +9-6-5+1-5+9-6+9-12+1+9+2+2+2+9-13+2+16-13-5+1+2+2-6+17-6-5+9-6-5+1+2+9+2+9-6-5+16-5+1-5+9+2+1+2-13+9+9-5-6+9+2-5+1-5+9-6+17-6-13+9+9-5+2 cpucycles observed persecond 2802000000...9240500000 with 1024 loops 3 microseconds cpucycles observed persecond 2977714285...4412200000 with 2048 loops 6 microseconds cpucycles observed persecond 3208083333...3927300000 with 4096 loops 11 microseconds cpucycles observed persecond 3486608695...3855952381 with 8192 loops 22 microseconds cpucycles observed persecond 3606500000...3832027778 with 16384 loops 37 microseconds cpucycles observed persecond 3644816666...3781258621 with 32768 loops 59 microseconds cpucycles observed persecond 3672697478...3740752137 with 65536 loops 118 microseconds cpucycles observed persecond 3687067510...3721102128 with 131072 loops 236 microseconds cpucycles observed persecond 3702415254...3719497873 with 262144 loops 471 microseconds cpucycles observed persecond 3705988335...3714527099 with 524288 loops 942 microseconds cpucycles observed persecond 3708108821...3712812798 with 1048576 loops 1892 microseconds ``` `cfarm120`, IBM POWER10, AlmaLinux 9.7, Linux kernel 5.14.0-427.31.1.el9_4.ppc64le: ``` cpucycles version 20260625 cpucycles tracesetup 0 ppc64-mftb precision 1023 scaling 5.750000 only32 0 cpucycles tracesetup 1 default-perfevent precision 139 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 1046 scaling 2.950000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 3980 scaling 2950.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2950000000 cpucycles implementation default-perfevent cpucycles iqm 136 +45+44+0+1+2+1+0+0+0+0+0+5+2+1+3+0+0+1+1+14+1+0+1+0+0+2+0+0+0+2+0+0+0+14+0+0+1+0+1+2+1+0+0+14+0+1+0+14+1+0+1+0+0+1+3+0+1+2+0+0+0+0+0+1 cpucycles observed persecond 1811000000...3992000000 with 2048 loops 3 microseconds cpucycles observed persecond 2836600000...4901333334 with 4096 loops 4 microseconds cpucycles observed persecond 2868444444...3754428572 with 8192 loops 8 microseconds cpucycles observed persecond 3355777777...3810062500 with 16384 loops 17 microseconds cpucycles observed persecond 3409464285...3692000000 with 32768 loops 27 microseconds cpucycles observed persecond 3736972222...3969617648 with 65536 loops 35 microseconds cpucycles observed persecond 3785605633...3901246377 with 131072 loops 70 microseconds cpucycles observed persecond 3830314285...3888688406 with 262144 loops 139 microseconds cpucycles observed persecond 3873345323...3902855073 with 524288 loops 277 microseconds cpucycles observed persecond 3884176795...3899293901 with 1048576 loops 542 microseconds ``` `cfarm185`, Ampere eMAG 8180, AlmaLinux 8.10, Linux kernel 4.18.0-553.el8_10.aarch64: ``` cpucycles version 20260625 cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1075 scaling 75.000000 only32 0 cpucycles tracesetup 3 default-perfevent precision 205 scaling 1.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1167 scaling 3.000000 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 4030 scaling 3000.000000 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3000000000 cpucycles implementation default-perfevent cpucycles iqm 264 -25-16-17+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 890000000...4520500000 with 1024 loops 3 microseconds cpucycles observed persecond 1082000000...1897250000 with 2048 loops 5 microseconds cpucycles observed persecond 1811000000...2751800000 with 4096 loops 6 microseconds cpucycles observed persecond 2257272727...2859777778 with 8192 loops 10 microseconds cpucycles observed persecond 2607736842...2970588236 with 16384 loops 18 microseconds cpucycles observed persecond 2901970588...3114531250 with 32768 loops 33 microseconds cpucycles observed persecond 3028430769...3138857143 with 65536 loops 64 microseconds cpucycles observed persecond 3074007812...3128968254 with 131072 loops 127 microseconds cpucycles observed persecond 3121726190...3149980000 with 262144 loops 251 microseconds cpucycles observed persecond 3127475149...3141540919 with 524288 loops 502 microseconds cpucycles observed persecond 3142828171...3149926927 with 1048576 loops 1000 microseconds ``` `cfarm202`, UltraSparc T5, Debian forky/sid, Linux kernel 6.17.0-rc5+: ``` cpucycles version 20260625 cpucycles tracesetup 0 sparc64-rdtick precision 65 scaling 1.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 448 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 1235 scaling 3.599910 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 4629 scaling 3599.910000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 3599910000 cpucycles implementation sparc64-rdtick cpucycles iqm 73 +24+0+24+24+24+0+0+24+0+0+1+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 2888000000...4979666667 with 4096 loops 4 microseconds cpucycles observed persecond 3197777777...4196285715 with 8192 loops 8 microseconds cpucycles observed persecond 3380235294...3863000000 with 16384 loops 16 microseconds cpucycles observed persecond 3479030303...3719000000 with 32768 loops 32 microseconds cpucycles observed persecond 3530707692...3650428572 with 65536 loops 64 microseconds cpucycles observed persecond 3584937500...3645658731 with 131072 loops 127 microseconds cpucycles observed persecond 3584468750...3614586615 with 262144 loops 255 microseconds cpucycles observed persecond 3591248532...3606304519 with 524288 loops 510 microseconds cpucycles observed persecond 3594648383...3602175663 with 1048576 loops 1020 microseconds ``` `cfarm216`, VM on SPARC-M8, Solaris 11.4.88.207.1: ``` cpucycles version 20260105 cpucycles tracesetup 0 sparc64-rdtick precision 63 scaling 1.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 614 scaling 5.067000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 5387 scaling 5067.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 5067000000 cpucycles implementation sparc64-rdtick cpucycles iqm 69 +0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+57376+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 2865000000...5940000000 with 4096 loops 3 microseconds cpucycles observed persecond 4597800000...7831000000 with 8192 loops 4 microseconds cpucycles observed persecond 4558600000...5760750000 with 16384 loops 9 microseconds cpucycles observed persecond 4765578947...5356647059 with 32768 loops 18 microseconds cpucycles observed persecond 4794418604...5041268293 with 65536 loops 42 microseconds cpucycles observed persecond 4968216216...5114986112 with 131072 loops 73 microseconds cpucycles observed persecond 4965598484...5044946154 with 262144 loops 131 microseconds cpucycles observed persecond 4984102661...5023766284 with 524288 loops 262 microseconds cpucycles observed persecond 4985677238...5005539326 with 1048576 loops 535 microseconds ``` `cfarm230`, Cavium Octeon III V0.2, Debian 10.13, Linux kernel 4.9.79-UBNT_E300: ``` cpucycles version 20260625 cpucycles tracesetup 0 mips64-cc precision 323 scaling 1.000000 only32 1 cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 2243 scaling 2.399988 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 3419 scaling 2399.987654 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation mips64-cc cpucycles iqm 405 +30+17+6+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0 cpucycles observed persecond 868444444...1931285715 with 1024 loops 8 microseconds cpucycles observed persecond 923437500...1160571429 with 2048 loops 15 microseconds cpucycles observed persecond 969766666...1089250000 with 4096 loops 29 microseconds cpucycles observed persecond 979067796...1037964913 with 8192 loops 58 microseconds cpucycles observed persecond 983837606...1013113044 with 16384 loops 116 microseconds cpucycles observed persecond 994792207...1009589520 with 32768 loops 230 microseconds cpucycles observed persecond 996036876...1003851852 with 65536 loops 460 microseconds cpucycles observed persecond 998830250...1002534352 with 131072 loops 918 microseconds cpucycles observed persecond 998601196...1000898149 with 262144 loops 1837 microseconds cpucycles observed persecond 999575323...1000699892 with 524288 loops 3703 microseconds cpucycles observed persecond 999797523...1000292365 with 1048576 loops 7348 microseconds ``` `cfarm400`, Loongson-3C5000L-LL, Debian trixie/sid, Linux kernel 6.1.0-rc7+: ``` cpucycles version 20260105 cpucycles tracesetup 0 loong64-rdtime precision 124 scaling 24.000000 only32 0 cpucycles tracesetup 1 default-perfevent precision 180 scaling 1.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 416 scaling 2.399988 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 2729 scaling 2399.987654 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation loong64-rdtime cpucycles iqm 48 +24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0 cpucycles observed persecond 1982400000...3408000000 with 4096 loops 4 microseconds cpucycles observed persecond 1975200000...2514000000 with 8192 loops 9 microseconds cpucycles observed persecond 2190666666...2482500000 with 16384 loops 17 microseconds cpucycles observed persecond 2315294117...2469000000 with 32768 loops 33 microseconds cpucycles observed persecond 2348776119...2425846154 with 65536 loops 66 microseconds cpucycles observed persecond 2383636363...2422892308 with 131072 loops 131 microseconds cpucycles observed persecond 2392425855...2411954023 with 262144 loops 262 microseconds cpucycles observed persecond 2392334600...2402061069 with 524288 loops 525 microseconds cpucycles observed persecond 2396822857...2401694657 with 1048576 loops 1049 microseconds ``` `cfarm425`, Ampere Altra Max M128-30, Debian forky, Linux kernel 6.16.12+deb14+1-arm64: ``` cpucycles version 20260625 cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 arm64-vct precision 1096 scaling 96.000000 only32 0 cpucycles tracesetup 3 default-perfevent precision 91 scaling 1.000000 only32 0 cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 5 default-monotonic precision 1116 scaling 2.399988 only32 0 cpucycles tracesetup 6 default-gettimeofday precision 3429 scaling 2399.987654 only32 0 cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation default-perfevent cpucycles iqm 82 +29-1-1-1-1-1+386-1-1-1+179-1-1+130+161-1+235-1-1-1-1+153+170-1-1+149-1-1-1+258+154-1-1-1-1-1-1-1-1-1-1+196+194-1+172-1-1-1-1-1-1-1+158-1-1+183-1-1-1-1-1-1-1+235 cpucycles observed persecond 547750000...1263500000 with 2048 loops 3 microseconds cpucycles observed persecond 852200000...1532333334 with 4096 loops 4 microseconds cpucycles observed persecond 1412166666...2203250000 with 8192 loops 5 microseconds cpucycles observed persecond 1822600000...2320375000 with 16384 loops 9 microseconds cpucycles observed persecond 2064187500...2383285715 with 32768 loops 15 microseconds cpucycles observed persecond 2266612903...2434482759 with 65536 loops 30 microseconds cpucycles observed persecond 2322280701...2412890910 with 131072 loops 56 microseconds cpucycles observed persecond 2391572727...2438981482 with 262144 loops 109 microseconds cpucycles observed persecond 2413564220...2437481482 with 524288 loops 217 microseconds cpucycles observed persecond 2432299539...2444340278 with 1048576 loops 433 microseconds ``` `cfarm430`, AMD EPYC 7773X, FreeBSD 16.0 VM: ``` cpucycles version 20260625 cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 amd64-tsc precision 1022 scaling 1.000000 only32 0 cpucycles tracesetup 4 amd64-tscasm precision 1032 scaling 1.000000 only32 0 cpucycles tracesetup 5 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 7 default-monotonic precision 1140 scaling 2.399988 only32 0 cpucycles tracesetup 8 default-gettimeofday precision 3429 scaling 2399.987654 only32 0 cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 2399987654 cpucycles implementation amd64-tsc cpucycles iqm 26 +40-4-4+18-4-4+150+18-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4-4+18-4-4+18-4-4+18-4-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4 cpucycles observed persecond 1578500000...3322000000 with 4096 loops 3 microseconds cpucycles observed persecond 1782000000...2569600000 with 8192 loops 6 microseconds cpucycles observed persecond 2053333333...2503600000 with 16384 loops 11 microseconds cpucycles observed persecond 2053040000...2245913044 with 32768 loops 24 microseconds cpucycles observed persecond 2189423076...2283600000 with 65536 loops 51 microseconds cpucycles observed persecond 2179614678...2224467290 with 131072 loops 108 microseconds cpucycles observed persecond 2189704433...2216746269 with 262144 loops 202 microseconds cpucycles observed persecond 2195588235...2211413979 with 524288 loops 373 microseconds cpucycles observed persecond 2196466750...2203708177 with 1048576 loops 796 microseconds ``` `z15`, IBM z15: ``` cpucycles version 20230106 cpucycles tracesetup 0 s390x-stckf precision 250 scaling 1.269531 only32 0 cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0 cpucycles tracesetup 3 default-monotonic precision 272 scaling 5.200000 only32 0 cpucycles tracesetup 4 default-gettimeofday precision 5400 scaling 5200.000000 only32 0 cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0 cpucycles persecond 5200000000 cpucycles implementation s390x-stckf cpucycles median 48 +87+8+0-2+0+0+38-2+0+1-3+1+28+0+3-3+1+0+28+0-2+3+0-2+36+0+0+0+1+0+28+0-2+0+3-2+35+1+0-2+0+3+28+0-2+0+0-2+3+25+3+0-2+0+1+35+1+0+0-2+0+28+0 cpucycles observed persecond 4948941176...5627733334 with 8192 loops 16 microseconds cpucycles observed persecond 4104125000...5515666667 with 16384 loops 7 microseconds cpucycles observed persecond 5047076923...5987818182 with 32768 loops 12 microseconds cpucycles observed persecond 5044846153...5475708334 with 65536 loops 25 microseconds cpucycles observed persecond 5141313725...5357428572 with 131072 loops 50 microseconds cpucycles observed persecond 5150892156...5257250000 with 262144 loops 101 microseconds cpucycles observed persecond 5183421568...5236549505 with 524288 loops 203 microseconds cpucycles observed persecond 5190282555...5216582717 with 1048576 loops 406 microseconds ``` libcpucycles-20260901/doc/cpucycles-info.md0000644000000000000000000000141315245636444017164 0ustar rootroot### NAME cpucycles-info - report information about CPU cycle counters ### SYNOPSIS cpucycles-info ### DESCRIPTION `cpucycles-info` prints human-readable information about the cycle counters considered by `cpucycles()`. The format is subject to change but currently includes a `cpucycles version` line, `cpucycles tracesetup` lines showing which cycle counters are considered and how precise they seem to be (with smaller `precision` values being better, except that `precision 0` means a cycle counter that does not seem to work), a `cpucycles persecond` line about the selected cycle counter, a `cpucycles implementation` line about the selected cycle counter, and `cpucycles observed persecond` lines about the selected cycle counter. ### SEE ALSO **cpucycles**(3) libcpucycles-20260901/doc/cpucycles-open.md0000644000000000000000000000076415245636444017202 0ustar rootroot### NAME cpucycles-open - open up cycle counting ### SYNOPSIS cpucycles-open ### DESCRIPTION `cpucycles-open` tries to change some aspects of OS configuration to open up higher-quality cycle counters for `cpucycles`. Some system administrators may wish to configure `cpucycles-open` to be run on each boot. However, what `cpucycles` does is contrary to some security policies. `cpucycles-open` often improves cycle counting, but does not guarantee success. ### SEE ALSO **cpucycles**(3) libcpucycles-20260901/doc/download.md0000644000000000000000000001503015245636444016050 0ustar rootrootTo download and unpack the latest version of libcpucycles: wget -m https://cpucycles.cr.yp.to/libcpucycles-latest-version.txt version=$(cat cpucycles.cr.yp.to/libcpucycles-latest-version.txt) wget -m https://cpucycles.cr.yp.to/libcpucycles-$version.tar.gz tar -xzf cpucycles.cr.yp.to/libcpucycles-$version.tar.gz cd libcpucycles-$version Then [install](install.html). ### Archives and changelog (reverse chronological) [`libcpucycles-20260901.tar.gz`](libcpucycles-20260901.tar.gz) [browse](libcpucycles-20260901.html) In `amd64-perfpmcff` and `default-perfevent`, use `/sys/bus/event_source/devices/cpu_atom/type` for the PMU type for Intel E-cores. This is observed to handle, e.g., Alder Lake E-cores with PMU type 8. Skip `amd64-perfpmcff` for PMC version <3 or for PMC width <48. This avoids a wraparound observed under Debian on two Core 2 CPUs from 2007 and 2009. (Those CPUs have PMC version 2 and PMC width 40. The observed wraparound is at 31 bits rather than 40 bits, presumably from continual usage of `wrmsr` by the OS.) Falling back to `default-perfevent` adds about 200 cycles to each cycle count on those CPUs, and adds about 500 cycles to each cycle count on an Airmont CPU from 2015. Adjust auto-generation scripts to auto-generate wrapper version and to avoid some Python 3.13 warnings. --- [`libcpucycles-20260625.tar.gz`](libcpucycles-20260625.tar.gz) [browse](libcpucycles-20260625.html) In `amd64-perfpmcff` and `default-perfevent`, to compensate for the Linux kernel [not doing](https://cr.yp.to/2026/20260624-rdpmc.c) what the `perf_event_open` manual page promises, try opening a second fd using PMU type 10 for Intel E-cores. This should prevent fallbacks to `tsc` for programs pinned to E-cores, and should let cycle counting continue for programs that migrate from P-cores to E-cores. Clear `/proc/sys/kernel/nmi_watchdog` in `cpucycles-open`. Otherwise the Linux NMI watchdog forces a wraparound after some number of seconds in RDPMC cycle counts from `amd64-perfpmcff`, corrupting multi-second cycle counts on Intel machines. AMD machines are unaffected. Increase bump to 1000 for all off-core counters and fixed-frequency counters. --- [`libcpucycles-20260105.tar.gz`](libcpucycles-20260105.tar.gz) [browse](libcpucycles-20260105.html) Bigger split of RDPMC-based counters to handle not just `perf` sometimes incorrectly returning index 0 on Intel but also AMD not supporting fixed-function counter `0x40000001`. New `amd64-perfpmcff` tries fixed-function counter `0x40000001` within `perf`; `amd64-perfpmc` now goes back to trying index returned by `perf`; `amd64-pmcff` (renamed from `amd64-pmc`) tries fixed-function counter `0x40000001` outside `perf`. Add `orderbump` mechanism, for example to prefer `tsc` more systematically over `tscasm`. --- [`libcpucycles-20251226.tar.gz`](libcpucycles-20251226.tar.gz) [browse](libcpucycles-20251226.html) Split `amd64-pmc`, `arm64-pmc`, `riscv32-rdcycle`, and `riscv64-rdcycle` into `perf` and non-`perf` versions, with the `perf` versions tried first. Hopefully the `perf` versions will also eliminate the need to install kernel modules for `amd64-pmc` and `arm64-pmc`. For `amd64-pmc`, always use fixed-function cycle counter `(1<<30)|1`. This works around a bug in, e.g., kernel 6.1.0 `perf` incorrectly returning index 0 for E-cores. For all `perf`-based counters, use `PERF_FLAG_FD_CLOEXEC` if it is available. For `*tsc*` counters, return invariant TSC frequency if that is clear from CPUID information. Thanks to Tee-Kiah Chia for the suggestion and a prototype patch. Add internal `ticks_close()`, most importantly for closing `perf` descriptors. (An alternative would be to unify the `perf` handling inside a single `perf_event_open` in `wrapper` conditioned on Linux, but this raises the question of how to handle `perf` platform variations such as `arm64-pmc` needing `3` in `config1`.) Increase penalty for `EXTEND32` counters. (It might be better to directly benchmark the extension.) Increase penalty for fixed-frequency counters, including RDTSC when it is known to be invariant. For `wrapper`, use `sigjmp_buf` instead of `jmp_buf`. Document requirements on `/sys/devices/cpu*/rdpmc` and `/proc/sys/kernel/perf_user_access`. Add `cpucycles-open` abstraction. Update `configure`: recognize a few more x86 synonyms; `--no-` instead of `--no`; support `configure.log`. Support `$DESTDIR` in `install`. Thanks to Robert Clausecker for the suggestion. --- [`libcpucycles-20250925.tar.gz`](libcpucycles-20250925.tar.gz) [browse](libcpucycles-20250925.html) For `perfevent`, try all combinations of disabling exclude-kernel and disabling exclude-hv, to handle platforms where cycle counters cannot handle one or both of those. For `perfevent`, do `DISABLE` and `ENABLE` around counter read (suggested by Jim Apple) to (hopefully) handle Graviton 3. But skip this if a setup test seems to work without it. Recognize `sun4v` as `sparc64`. Add support for `loong64`. Eliminate various compiler warnings. For `cpucycles-info`, print interquartile mean (iqm) rather than median. Say "sometimes" in documentation for enabling cycle counters in ARM via kernel modules. Change HTML style, in particular for better usability on phones. --- [`libcpucycles-20240318.tar.gz`](libcpucycles-20240318.tar.gz) [browse](libcpucycles-20240318.html) Port to MacOS X: handle missing `-lrt`, and handle differences in shared-library naming. Include `cpucycles-info` man page. --- [`libcpucycles-20240114.tar.gz`](libcpucycles-20240114.tar.gz) [browse](libcpucycles-20240114.html) Add `arm32-1176` counter. Allow slop 0.2 rather than 0.1 for `FINDMULTIPLIER`. Improve platform detection. Port to FreeBSD. Use blue boldface during compilation for "skipping option that did not compile". `doc/install.md`: headings; note manual pages. Add `doc/license.md`. Update HTML style for better tt visibility and copy-paste. --- [`libcpucycles-20230115.tar.gz`](libcpucycles-20230115.tar.gz) [browse](libcpucycles-20230115.html) Update actual `cpucycles_version` behavior to match documentation. --- [`libcpucycles-20230110.tar.gz`](libcpucycles-20230110.tar.gz) [browse](libcpucycles-20230110.html) `doc/api.md`: Document `cpucycles_version()`. Add `s390x-stckf` counter. `cpucycles/default-perfevent.c`: Read into `int64_t` instead of `long long`. Add comment explaining issues with `PERF_FORMAT_TOTAL_TIME_RUNNING`. `configure`: Improve `uname` handling. `doc/api.md`: Update description of default frequency. --- [`libcpucycles-20230105.tar.gz`](libcpucycles-20230105.tar.gz) [browse](libcpucycles-20230105.html) Initial release. libcpucycles-20260901/doc/html/0000755000000000000000000000000015245636444014664 5ustar rootrootlibcpucycles-20260901/doc/html/api.html0000444000000000000000000001356215245636444016330 0ustar rootroot libcpucycles: API
libcpucycles: API

NAME

cpucycles - count CPU cycles

SYNOPSIS

#include <cpucycles.h>

long long count = cpucycles();
long long persecond = cpucycles_persecond();
const char *implementation = cpucycles_implementation();
const char *version = cpucycles_version();

Link with -lcpucycles. Old systems may also need -lrt.

DESCRIPTION

cpucycles() returns an estimate for the number of CPU cycles that have occurred since an unspecified time in the past (perhaps system boot, perhaps program startup).

Accessing true cycle counters can be difficult on some CPUs and operating systems. cpucycles() does its best to produce accurate results, but selects a low-precision counter if the only other option is failure.

cpucycles_persecond() returns an estimate for the number of CPU cycles per second. This estimate comes from /etc/cpucyclespersecond if that file exists, otherwise from various OS mechanisms, otherwise from the cpucyclespersecond environment variable if that is set, otherwise 2399987654.

cpucycles_implementation() returns the name of the counter in use: e.g., "amd64-perfpmc".

cpucycles_version() returns the libcpucycles version number as a string: e.g., "20260901". Results of cpucycles_implementation() should be interpreted relative to cpucycles_version().

cpucycles is actually a function pointer. The first call to cpucycles() or cpucycles_persecond() or cpucycles_implementation() selects one of the available counters and updates the cpucycles pointer accordingly. Subsequent calls to cpucycles() are thread-safe.

SEE ALSO

gettimeofday(2), clock_gettime(2)


Version: This is version 2026.09.01 of the "API" web page.
libcpucycles-20260901/doc/html/counters.html0000444000000000000000000025072215245636444017422 0ustar rootroot libcpucycles: Counters
libcpucycles: Counters

Currently libcpucycles supports the following cycle counters. Some cycle counters are actually other forms of counters that libcpucycles scales to imitate a cycle counter. There is separate documentation for how libcpucycles makes a choice of cycle counter. There is a cpucycles-open command that, when run as root, often succeeds in enabling higher-quality cycle counters until reboot. See the security considerations regarding enabling or disabling counters and regarding overclocking (Turbo Boost, Turbo Core, etc.).

amd64-perfpmcff: Requires a 64-bit Intel platform; the Linux perf_event interface; /proc/sys/kernel/perf_event_paranoid at most 2; any existing files among /sys/devices/{cpu,cpu_core,cpu_atom}/rdpmc at least 2. Accesses a cycle counter through RDPMC (using Intel-specific counter 0x40000001, which is why this ends up not running on AMD CPUs). This counter runs at the clock frequency of the CPU core. Starting with libcpucycles version 20260625, this counter tries to compensate for a perf_event bug in handling Intel E-cores. Starting with libcpucycles version 20260901, the counter tries harder to compensate; also, this counter is skipped on cores with PMC version <3 or PMC width <48.

amd64-perfpmc: Requires a 64-bit AMD platform; the Linux perf_event interface; /proc/sys/kernel/perf_event_paranoid at most 2; any existing files among /sys/devices/{cpu,cpu_core,cpu_atom}/rdpmc at least 2. Accesses a cycle counter through RDPMC (using the perf_event index); to avoid various amd64-perfpmcff complications, actively refuses to run on Intel. This counter runs at the clock frequency of the CPU core.

amd64-pmcff: Requires a 64-bit Intel platform and an OS that enables user-level RDPMC access. Accesses a cycle counter through RDPMC (using Intel-specific counter 0x40000001, which is why this ends up not running on AMD CPUs). This counter runs at the clock frequency of the CPU core.

amd64-tsc, amd64-tscasm: Requires a 64-bit Intel/AMD platform. Requires RDTSC to be enabled, which it is by default. Uses RDTSC to access the CPU's time-stamp counter. On current CPUs, this is an off-core clock rather than a cycle counter, but it is typically a very fast off-core clock, making it adequate for seeing cycle counts if overclocking and underclocking are disabled. The difference between tsc and tscasm is that tsc uses the compiler's __rdtsc() while tscasm uses inline assembly.

arm32-cortex: Requires a 32-bit ARMv7-A platform. Uses mrc p15, 0, %0, c9, c13, 0 to read the cycle counter. Requires user access to the cycle counter, which is not enabled by default but can (sometimes) be enabled under Linux via a kernel module. This counter is natively 32 bits, but libcpucycles watches how the counter and gettimeofday increase to compute a 64-bit extension of the counter.

arm32-1176: Requires a 32-bit ARM1176 platform. Uses mrc p15, 0, %0, c15, c12, 1 to read the cycle counter. Requires user access to the cycle counter, which is not enabled by default but can (sometimes) be enabled under Linux via a kernel module. This counter is natively 32 bits, but libcpucycles watches how the counter and gettimeofday increase to compute a 64-bit extension of the counter.

arm64-perfpmc: Requires a 64-bit ARMv8-A platform; the Linux perf_event interface; on current Linux kernels, 1 in /proc/sys/kernel/perf_user_access; on older Linux kernels, a kernel module to enable PMCCNTR access. Uses mrs %0, PMCCNTR_EL0 to read the cycle counter.

arm64-pmc: Requires a 64-bit ARMv8-A platform and an OS that enables user-level PMCCNTR access, for example an older Linux kernel with a kernel module. Uses mrs %0, PMCCNTR_EL0 to read the cycle counter.

arm64-vct: Requires a 64-bit ARMv8-A platform. Uses mrs %0, CNTVCT_EL0 to read a "virtual count" timer. This is an off-core clock, typically running at 24MHz. Results are scaled by libcpucycles.

loong64-rdtime: Requires a 64-bit LoongArch platform. Uses rdtime.d to read the "constant frequency timer". This is an off-core clock, typically running at 100MHz.

mips64-cc: Requires a 64-bit MIPS platform. (Maybe the same code would also work as mips32-cc, but this has not been tested yet.) Uses RDHWR to read the hardware cycle counter (hardware register 2 times a constant scale factor in hardware register 3). This counter is natively 32 bits, but libcpucycles watches how the counter and gettimeofday increase to compute a 64-bit extension of the counter.

ppc32-mftb: Requires a 32-bit PowerPC platform. Uses mftb and mftbu to read the "time base". This is an off-core clock, typically running at 24MHz.

ppc64-mftb: Requires a 64-bit PowerPC platform. Uses mftb and mftbu to read the "time base". This is an off-core clock, typically running at 24MHz.

riscv32-perfrdcycle: Requires a 32-bit RISC-V platform; the Linux perf_event interface; on current Linux kernels, 1 in /proc/sys/kernel/perf_user_access. Uses rdcycle and rdcycleh to read a cycle counter.

riscv32-rdcycle: Requires a 32-bit RISC-V platform and an OS that enables user-level rdcycle access. Uses rdcycle and rdcycleh to read a cycle counter.

riscv64-perfrdcycle: Requires a 64-bit RISC-V platform; the Linux perf_event interface; on current Linux kernels, 1 in /proc/sys/kernel/perf_user_access. Uses rdcycle to read a cycle counter.

riscv64-rdcycle: Requires a 64-bit RISC-V platform and an OS that enables user-level rdcycle access. Uses rdcycle to read a cycle counter.

s390x-stckf: Requires a 64-bit z/Architecture platform. Uses stckf to read the TOD clock, which is documented to run at 4096MHz. On the z15, this looks like a doubling of an off-core 2048MHz clock. Results are scaled by libcpucycles.

sparc64-rdtick: Requires a 64-bit SPARC platform. Uses rd %tick to read a cycle counter.

x86-tsc, x86-tscasm: Same as amd64-tsc and amd64-tscasm, but for 32-bit Intel/AMD platforms instead of 64-bit Intel/AMD platforms.

default-gettimeofday: Reasonably portable. Resolution is limited to 1 microsecond. Results are scaled by libcpucycles.

default-mach: Requires an OS with mach_absolute_time(). Typically runs at 24MHz. Results are scaled by libcpucycles.

default-monotonic: Requires CLOCK_MONOTONIC. Reasonably portable, although might fail on older systems where default-gettimeofday works. Resolution is limited to 1 nanosecond. Can be almost as good as a cycle counter, or orders of magnitude worse, depending on the OS and CPU. Results are scaled by libcpucycles.

default-perfevent: Requires the Linux perf_event interface, and a CPU where perf_event supports PERF_COUNT_HW_CPU_CYCLES. Similar variations in quality to default-monotonic, without the 1-nanosecond limitation. Starting with libcpucycles version 20260625, this counter tries to compensate for a perf_event bug in handling Intel E-cores. Starting with libcpucycles version 20260901, the counter tries harder to compensate.

default-zero: The horrifying last resort if nothing else works.

Examples

These are examples of cpucycles-info output on various machines. The machines named cfarm* are from the cfarm compile farm.

A median line saying, e.g., 47 +47+28+0+2-5+0+2-5... means that the differences between adjacent cycle counts were 47+47, 47+28, 47+0, 47+2, 47−5, 47+0, 47+2, 47−5, etc., with median difference 47. The first few differences are typically larger because of cache effects. Current versions of libcpucycles use iqm (interquartile mean) instead of median.

berry0, Broadcom BCM2835:

cpucycles version 20240114
cpucycles tracesetup 0 arm32-cortex precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 arm32-1176 precision 22 scaling 1.000000 only32 1
cpucycles tracesetup 2 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 1199 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 1200 scaling 1000.000000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1000000000
cpucycles implementation arm32-1176
cpucycles median 720 +942+124+1+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+2+0+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+222+300+1+0+0+2+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 798307692...2045181819 with 1024 loops 12 microseconds
cpucycles observed persecond 915478260...1260523810 with 2048 loops 22 microseconds
cpucycles observed persecond 947809523...1106100000 with 4096 loops 41 microseconds
cpucycles observed persecond 966353658...1129037500 with 8192 loops 81 microseconds
cpucycles observed persecond 988490566...1030019109 with 16384 loops 158 microseconds
cpucycles observed persecond 995169327...1002034063 with 32768 loops 2379 microseconds
cpucycles observed persecond 996871019...1012568691 with 65536 loops 627 microseconds
cpucycles observed persecond 997832134...1004212170 with 131072 loops 1250 microseconds
cpucycles observed persecond 997740918...1000887780 with 262144 loops 5009 microseconds
cpucycles observed persecond 998528349...1001961164 with 524288 loops 5537 microseconds
cpucycles observed persecond 999202882...1001166794 with 1048576 loops 10547 microseconds

berry2, Broadcom BCM2836:

cpucycles version 20251226
cpucycles tracesetup 0 arm32-cortex precision 310 scaling 1.000000 only32 1
cpucycles tracesetup 1 arm32-1176 precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 254 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 814 scaling 0.900000 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 1200 scaling 900.000000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 900000000
cpucycles implementation default-perfevent
cpucycles iqm 154 +208+9+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+173+172+29+0-4+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 218360000...420565218 with 1024 loops 24 microseconds
cpucycles observed persecond 327781250...402566667 with 2048 loops 31 microseconds
cpucycles observed persecond 423204081...468085107 with 4096 loops 48 microseconds
cpucycles observed persecond 490369047...517231708 with 8192 loops 83 microseconds
cpucycles observed persecond 544033112...560208054 with 16384 loops 150 microseconds
cpucycles observed persecond 450227397...457187328 with 32768 loops 364 microseconds
cpucycles observed persecond 584518716...588967800 with 65536 loops 560 microseconds
cpucycles observed persecond 592214995...594508598 with 131072 loops 1106 microseconds
cpucycles observed persecond 595894545...597049591 with 262144 loops 2199 microseconds
cpucycles observed persecond 598008895...598558878 with 524288 loops 4383 microseconds
cpucycles observed persecond 595624105...595918873 with 1048576 loops 8802 microseconds

pi3aplus, Broadcom BCM2837B0:

cpucycles version 20260625
cpucycles tracesetup 0 arm64-perfpmc precision 9 scaling 1.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1083 scaling 73.000000 only32 0
cpucycles tracesetup 3 default-perfevent precision 130 scaling 1.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1102 scaling 1.400000 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 2440 scaling 1400.000000 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1400000000
cpucycles implementation arm64-perfpmc
cpucycles iqm 10 +15+8+8+3+0+0+0+0+0+0+0+7-2-2-2-1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 1030500000...2158500000 with 2048 loops 3 microseconds
cpucycles observed persecond 1177285714...1688600000 with 4096 loops 6 microseconds
cpucycles observed persecond 1369333333...1662000000 with 8192 loops 11 microseconds
cpucycles observed persecond 1367000000...1499454546 with 16384 loops 23 microseconds
cpucycles observed persecond 1366166666...1429565218 with 32768 loops 47 microseconds
cpucycles observed persecond 1394808510...1427086957 with 65536 loops 93 microseconds
cpucycles observed persecond 1165577777...1177856503 with 131072 loops 224 microseconds
cpucycles observed persecond 1379878947...1387708995 with 262144 loops 379 microseconds
cpucycles observed persecond 1390775862...1394730054 with 524288 loops 753 microseconds
cpucycles observed persecond 1364528952...1366583714 with 1048576 loops 1536 microseconds

pi4b, Broadcom BCM2711, Ubuntu 24.04, Linux kernel 6.8.0-1036-raspi, running in power-saving mode (echo powersave > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor):

cpucycles version 20260901
cpucycles tracesetup 0 arm64-perfpmc precision 9 scaling 1.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1037 scaling 27.750000 only32 0
cpucycles tracesetup 3 default-perfevent precision 179 scaling 1.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1252 scaling 1.500000 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 2540 scaling 1500.000000 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1500000000
cpucycles implementation arm64-perfpmc
cpucycles iqm 9 +40+1+0+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 423800000...803333334 with 1024 loops 4 microseconds
cpucycles observed persecond 520875000...729000000 with 2048 loops 7 microseconds
cpucycles observed persecond 550866666...649076924 with 4096 loops 14 microseconds
cpucycles observed persecond 587678571...640961539 with 8192 loops 27 microseconds
cpucycles observed persecond 586410714...611962963 with 16384 loops 55 microseconds
cpucycles observed persecond 596427272...609388889 with 32768 loops 109 microseconds
cpucycles observed persecond 596104545...602522936 with 65536 loops 219 microseconds
cpucycles observed persecond 560482905...563418455 with 131072 loops 467 microseconds
cpucycles observed persecond 581430155...582961112 with 262144 loops 901 microseconds
cpucycles observed persecond 587575350...588363433 with 524288 loops 1784 microseconds
cpucycles observed persecond 590009001...590410639 with 1048576 loops 3554 microseconds

pi5, Broadcom BCM2712, Debian 12, Linux kernel 6.12.25+rpt-rpi-2712, running in power-saving mode (echo powersave > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor):

cpucycles version 20260625
cpucycles tracesetup 0 arm64-perfpmc precision 2 scaling 1.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1054 scaling 44.500000 only32 0
cpucycles tracesetup 3 default-perfevent precision 97 scaling 1.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1162 scaling 2.400000 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 3440 scaling 2400.000000 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2400000000
cpucycles implementation arm64-perfpmc
cpucycles iqm 7 +11+12+1+12+1+12+1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+3-3+2+1-3+2-2+0+0+0+0+0+3-3+2-2+0+0+0+0+3-3+2-2+0+0+0+0+3-3+2-2+0+0+0+0+0+0+0
cpucycles observed persecond 1034000000...2137000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1178428571...1673800000 with 8192 loops 6 microseconds
cpucycles observed persecond 1370416666...1656500000 with 16384 loops 11 microseconds
cpucycles observed persecond 1426434782...1568000000 with 32768 loops 22 microseconds
cpucycles observed persecond 1457222222...1527790698 with 65536 loops 44 microseconds
cpucycles observed persecond 1489897727...1525930233 with 131072 loops 87 microseconds
cpucycles observed persecond 1489687500...1507494253 with 262144 loops 175 microseconds
cpucycles observed persecond 1493823361...1502727794 with 524288 loops 350 microseconds
cpucycles observed persecond 1495885877...1500337626 with 1048576 loops 700 microseconds

bblack, TI Sitara XAM3359AZCZ100:

cpucycles version 20260625
cpucycles tracesetup 0 arm32-cortex precision 308 scaling 1.000000 only32 1
cpucycles tracesetup 1 arm32-1176 precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 2134 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 2020 scaling 1000.000000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1000000000
cpucycles implementation arm32-cortex
cpucycles iqm 1260 +166+5+19+0+10+0+0+0+0+0+0+0+0+0+0+0+0+10+0+0+0+2+8+0+0+0+0+0+0+2+8+2+8+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+12+8+0+0+10+0+0+0+0+10+0+2+8+0+0
cpucycles observed persecond 625636363...5378111112 with 1024 loops 10 microseconds
cpucycles observed persecond 768600000...1400692308 with 2048 loops 14 microseconds
cpucycles observed persecond 869240000...1162217392 with 4096 loops 24 microseconds
cpucycles observed persecond 938333333...1097976745 with 8192 loops 44 microseconds
cpucycles observed persecond 956057471...1037282353 with 16384 loops 86 microseconds
cpucycles observed persecond 977035502...1018814372 with 32768 loops 168 microseconds
cpucycles observed persecond 987789789...1008755288 with 65536 loops 332 microseconds
cpucycles observed persecond 994892424...1005542554 with 131072 loops 659 microseconds
cpucycles observed persecond 997695057...1002990861 with 262144 loops 1314 microseconds
cpucycles observed persecond 998862529...1000671667 with 524288 loops 6735 microseconds
cpucycles observed persecond 999072352...1000502726 with 1048576 loops 9356 microseconds

titan0, Intel Xeon E3-1275 V3:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 37 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1034 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1044 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 114 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1106 scaling 3.500000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 4550 scaling 3500.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3500000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 41 +40+40+20+20-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0-1+2-2+0
cpucycles observed persecond 2751166666...4174000000 with 16384 loops 5 microseconds
cpucycles observed persecond 3285200000...4136000000 with 32768 loops 9 microseconds
cpucycles observed persecond 3177258064...3406413794 with 65536 loops 30 microseconds
cpucycles observed persecond 3294750000...3473105264 with 131072 loops 39 microseconds
cpucycles observed persecond 3405415584...3498733334 with 262144 loops 76 microseconds
cpucycles observed persecond 3472529801...3520382551 with 524288 loops 150 microseconds
cpucycles observed persecond 3472317880...3496096667 with 1048576 loops 301 microseconds

wolfdale, Intel Core 2 Duo E7600:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1069 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1079 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 255 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 5921 scaling 3.059000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 4099 scaling 3059.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3059000000
cpucycles implementation default-perfevent
cpucycles iqm 242 +0+0+0+0+0+4+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 345142857...1156200000 with 1024 loops 6 microseconds
cpucycles observed persecond 551000000...927166667 with 2048 loops 7 microseconds
cpucycles observed persecond 847800000...1201125000 with 4096 loops 9 microseconds
cpucycles observed persecond 1041875000...1272428572 with 8192 loops 15 microseconds
cpucycles observed persecond 1271307692...1424875000 with 16384 loops 25 microseconds
cpucycles observed persecond 1255358490...1328470589 with 32768 loops 52 microseconds
cpucycles observed persecond 1492704545...1540976745 with 65536 loops 87 microseconds
cpucycles observed persecond 1543705882...1568791667 with 131072 loops 169 microseconds
cpucycles observed persecond 1565892537...1578696697 with 262144 loops 334 microseconds
cpucycles observed persecond 1579611445...1586093656 with 524288 loops 663 microseconds
cpucycles observed persecond 1585365079...1588622256 with 1048576 loops 1322 microseconds

nucnuc, Intel Pentium N3700 (Airmont, 40-bit PMC):

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1020 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1030 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 386 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1150 scaling 1.600000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2640 scaling 1600.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1600000000
cpucycles implementation default-perfevent
cpucycles iqm 506 -5-3-19+0+0+0+0+0+0+0+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+14+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 462166666...2148500000 with 1024 loops 5 microseconds
cpucycles observed persecond 666714285...1241400000 with 2048 loops 6 microseconds
cpucycles observed persecond 874600000...1281625000 with 4096 loops 9 microseconds
cpucycles observed persecond 1135866666...1425846154 with 8192 loops 14 microseconds
cpucycles observed persecond 1332840000...1513869566 with 16384 loops 24 microseconds
cpucycles observed persecond 1436847826...1536227273 with 32768 loops 45 microseconds
cpucycles observed persecond 1514149425...1567435295 with 65536 loops 86 microseconds
cpucycles observed persecond 1554414201...1582000000 with 131072 loops 168 microseconds
cpucycles observed persecond 1580843373...1594954546 with 262144 loops 331 microseconds
cpucycles observed persecond 1536684133...1547656935 with 524288 loops 686 microseconds
cpucycles observed persecond 1594012917...1597585236 with 1048576 loops 1315 microseconds

gemini, Intel Celeron N4020 (Goldmont, 48-bit PMC):

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1033 scaling 1.005117 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1040 scaling 1.005117 only32 0
cpucycles tracesetup 5 default-perfevent precision 135 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1118 scaling 1.100000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2150 scaling 1100.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1100000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 17 +11+11+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1-1-1+1+1
cpucycles observed persecond 835000000...2161666667 with 1024 loops 4 microseconds
cpucycles observed persecond 919555555...1244428572 with 2048 loops 8 microseconds
cpucycles observed persecond 1027750000...1205642858 with 4096 loops 15 microseconds
cpucycles observed persecond 1058967741...1147000000 with 8192 loops 30 microseconds
cpucycles observed persecond 1075344262...1119169492 with 16384 loops 60 microseconds
cpucycles observed persecond 1083735537...1105605043 with 32768 loops 120 microseconds
cpucycles observed persecond 1087983402...1098907950 with 65536 loops 240 microseconds
cpucycles observed persecond 1094672233...1100044026 with 131072 loops 478 microseconds
cpucycles observed persecond 1095753396...1098503665 with 262144 loops 956 microseconds
cpucycles observed persecond 1096294824...1097637363 with 524288 loops 1912 microseconds
cpucycles observed persecond 1091311134...1092790995 with 1048576 loops 3843 microseconds

saber214, AMD FX-8350, running under Xen:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1071 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1080 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1188 scaling 4.013514 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 5043 scaling 4013.514000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 4013514000
cpucycles implementation amd64-tsc
cpucycles iqm 72 +44-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0-1+1-1+0-1+0+0+0-1+0+0+0-1+0-1+1-1+0-1+0+0
cpucycles observed persecond 3018000000...6236500000 with 4096 loops 3 microseconds
cpucycles observed persecond 3438000000...4895800000 with 8192 loops 6 microseconds
cpucycles observed persecond 3695615384...4404090910 with 16384 loops 12 microseconds
cpucycles observed persecond 4001083333...4382909091 with 32768 loops 23 microseconds
cpucycles observed persecond 3916714285...4091872341 with 65536 loops 48 microseconds
cpucycles observed persecond 3997031250...4086319149 with 131072 loops 95 microseconds
cpucycles observed persecond 3996567708...4040752632 with 262144 loops 191 microseconds
cpucycles observed persecond 4005274271...4025941464 with 524288 loops 411 microseconds
cpucycles observed persecond 4006639686...4017687173 with 1048576 loops 765 microseconds

phoenix, AMD Ryzen 5 7640HS:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 34 scaling 1.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1011 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1021 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 176 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1126 scaling 4.301000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 5351 scaling 4301.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 4301000000
cpucycles implementation amd64-perfpmc
cpucycles iqm 34 +35+0+0+0+0+0+0+471+0+0+0+0+0+0+0+0+0+0+0+459-1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 3289200000...5535333334 with 16384 loops 4 microseconds
cpucycles observed persecond 3647777777...4715285715 with 32768 loops 8 microseconds
cpucycles observed persecond 3858705882...4383866667 with 65536 loops 16 microseconds
cpucycles observed persecond 4097937500...4376466667 with 131072 loops 31 microseconds
cpucycles observed persecond 4162000000...4301081968 with 262144 loops 62 microseconds
cpucycles observed persecond 4228629032...4299262296 with 524288 loops 123 microseconds
cpucycles observed persecond 4228379032...4263406505 with 1048576 loops 247 microseconds

alder2, Intel Core i3-1215U, P-core:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 8 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1045 scaling 0.480769 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1055 scaling 0.480769 only32 0
cpucycles tracesetup 5 default-perfevent precision 108 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1137 scaling 1.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 11 +57+37+32+7+2+4+2+2+1+0-1+0-1+1+1+0+0+1-3+2-2+2-2+3-2+1+1+0-2+1-1+2-3+3-1+1-3+3-1+0-1+1-1+2-2+2-3+2-2+2-2+1-1+3+0-1+1-2+2-2+0+0+2-1
cpucycles observed persecond 556400000...966333334 with 4096 loops 4 microseconds
cpucycles observed persecond 698250000...955666667 with 8192 loops 7 microseconds
cpucycles observed persecond 735533333...857769231 with 16384 loops 14 microseconds
cpucycles observed persecond 784107142...848961539 with 32768 loops 27 microseconds
cpucycles observed persecond 782250000...813518519 with 65536 loops 55 microseconds
cpucycles observed persecond 795663636...811490741 with 131072 loops 109 microseconds
cpucycles observed persecond 795159090...802986239 with 262144 loops 219 microseconds
cpucycles observed persecond 796719817...800631579 with 524288 loops 438 microseconds
cpucycles observed persecond 960726648...963537191 with 1048576 loops 727 microseconds

alder2, Intel Core i3-1215U, E-core:

cpucycles version 20260901
cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1055 scaling 0.480769 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1065 scaling 0.480769 only32 0
cpucycles tracesetup 5 default-perfevent precision 122 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1139 scaling 1.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 17 +11+1-1+1-1+1-1+1-1+1-1+1+3-3-1+1-1+1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+3-1-1-1+3-3+3-3+1-1+2-1-1+2-1-1+1-1+1-1+1-1+1-1+1-1+3-3+2-1-1+1
cpucycles observed persecond 835200000...1431666667 with 2048 loops 4 microseconds
cpucycles observed persecond 769545454...955555556 with 4096 loops 10 microseconds
cpucycles observed persecond 829900000...929555556 with 8192 loops 19 microseconds
cpucycles observed persecond 860500000...909342106 with 16384 loops 39 microseconds
cpucycles observed persecond 892932432...919611112 with 32768 loops 73 microseconds
cpucycles observed persecond 893517006...906758621 with 65536 loops 146 microseconds
cpucycles observed persecond 895385665...902000000 with 131072 loops 292 microseconds
cpucycles observed persecond 896545299...899850772 with 262144 loops 584 microseconds
cpucycles observed persecond 897159110...898811483 with 524288 loops 1168 microseconds
cpucycles observed persecond 892638605...893458298 with 1048576 loops 2351 microseconds

freshwrap, Intel Core 5 210H, P-core:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1049 scaling 0.818452 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1059 scaling 0.818452 only32 0
cpucycles tracesetup 5 default-perfevent precision 142 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1103 scaling 2.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 3250 scaling 2200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 14 +55+27-3-1+0+3-1+1+0+3+5-3+5-1+5-2+3-1+2-1+0+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0-1+0+0+1-1+1+0
cpucycles observed persecond 1828333333...2773500000 with 16384 loops 5 microseconds
cpucycles observed persecond 1991818181...2450777778 with 32768 loops 10 microseconds
cpucycles observed persecond 2082761904...2308368422 with 65536 loops 20 microseconds
cpucycles observed persecond 2132878048...2245358975 with 131072 loops 40 microseconds
cpucycles observed persecond 2165755813...2218761905 with 262144 loops 85 microseconds
cpucycles observed persecond 2185543750...2213962026 with 524288 loops 159 microseconds
cpucycles observed persecond 2189342679...2203442007 with 1048576 loops 320 microseconds

freshwrap, Intel Core 5 210H, E-core:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1049 scaling 0.818452 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1059 scaling 0.818452 only32 0
cpucycles tracesetup 5 default-perfevent precision 121 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1143 scaling 2.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 3250 scaling 2200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 17 +21+22+1+3-3+1-1+2-1-1+1-1+3-3+1-1+3-1-1-1+1-1+1-1+1-1+1-1+2-1-1+2-1-1+1-1+1-1+1-1+1-1+1-1+3-3+2-1-1+1-1+3-3+2-1-1+1-1+1-1+2-1-1+1
cpucycles observed persecond 1060750000...2189000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1275571428...1819800000 with 8192 loops 6 microseconds
cpucycles observed persecond 1475250000...1787300000 with 16384 loops 11 microseconds
cpucycles observed persecond 1525217391...1678571429 with 32768 loops 22 microseconds
cpucycles observed persecond 1541955555...1617651163 with 65536 loops 44 microseconds
cpucycles observed persecond 1575720930...1615285715 with 131072 loops 85 microseconds
cpucycles observed persecond 1581636904...1601716868 with 262144 loops 167 microseconds
cpucycles observed persecond 1593329305...1603534955 with 524288 loops 330 microseconds
cpucycles observed persecond 1595613050...1600729072 with 1048576 loops 658 microseconds

meteor, Intel Core Ultra 5 125H, P-core:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 8 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1033 scaling 0.400641 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1043 scaling 0.400641 only32 0
cpucycles tracesetup 5 default-perfevent precision 143 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1104 scaling 1.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 20 +55+25+0+3-4+3+2+9-7-3-3-3-4+0-2+0-4-1-3-3-4-1-1-6-3-3+2+1+6-2-1+10-12+6+2+4-9+2+0-1-1+40-7+3+0+2+0+4-4-1-6-3-3-6+4+3+5-4+12+1+8+10+12+5
cpucycles observed persecond 938750000...1949000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1055500000...1458500000 with 8192 loops 7 microseconds
cpucycles observed persecond 1057875000...1219928572 with 16384 loops 15 microseconds
cpucycles observed persecond 1176060606...1258387097 with 32768 loops 32 microseconds
cpucycles observed persecond 1169929824...1215672728 with 65536 loops 56 microseconds
cpucycles observed persecond 1190088888...1218943182 with 131072 loops 89 microseconds
cpucycles observed persecond 1189457317...1205123457 with 262144 loops 163 microseconds
cpucycles observed persecond 1193379870...1201712419 with 524288 loops 307 microseconds
cpucycles observed persecond 1196813021...1201098828 with 1048576 loops 598 microseconds

meteor, Intel Core Ultra 5 125H, E-core:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 14 scaling 1.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1059 scaling 0.400641 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1068 scaling 0.400641 only32 0
cpucycles tracesetup 5 default-perfevent precision 124 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1167 scaling 1.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 2250 scaling 1200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1200000000
cpucycles implementation amd64-perfpmcff
cpucycles iqm 17 +1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+1-1+2-1-1+1-1+3-3+1-1+1-1+1-1+2-1-1+1-1+1-1+1-1+1-1+2-1-1+1-1+2-1-1+1-1+2-1-1+1-1+1-1+1-1+1-1+1-1
cpucycles observed persecond 439200000...770666667 with 2048 loops 4 microseconds
cpucycles observed persecond 608857142...878200000 with 4096 loops 6 microseconds
cpucycles observed persecond 638000000...764363637 with 8192 loops 12 microseconds
cpucycles observed persecond 687750000...756136364 with 16384 loops 23 microseconds
cpucycles observed persecond 670959183...701978724 with 32768 loops 48 microseconds
cpucycles observed persecond 691105263...707182796 with 65536 loops 94 microseconds
cpucycles observed persecond 694132275...702160428 with 131072 loops 188 microseconds
cpucycles observed persecond 667098984...671061225 with 262144 loops 393 microseconds
cpucycles observed persecond 697416223...699448000 with 524288 loops 751 microseconds
cpucycles observed persecond 697739188...698754164 with 1048576 loops 1502 microseconds

cfarm14, Intel Xeon E5-2620 v3, Debian 12, Linux kernel 6.1.0-26-amd64:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1018 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1028 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 84 scaling 1.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1110 scaling 3.200000 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 4240 scaling 3200.000000 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3200000000
cpucycles implementation default-perfevent
cpucycles iqm 74 +50+0+0+0+0+0+0+0+0-2+1+0+2+0+0+0+1+0+0+0+0+0+0-2+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+0+1+1+0-2+0+0+2+0-2-2-2
cpucycles observed persecond 541000000...1232500000 with 2048 loops 3 microseconds
cpucycles observed persecond 1053750000...2229000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1385500000...2138750000 with 8192 loops 5 microseconds
cpucycles observed persecond 1833555555...2392857143 with 16384 loops 8 microseconds
cpucycles observed persecond 2192533333...2549230770 with 32768 loops 14 microseconds
cpucycles observed persecond 2344750000...2534730770 with 65536 loops 27 microseconds
cpucycles observed persecond 2475471698...2577333334 with 131072 loops 52 microseconds
cpucycles observed persecond 2522778846...2574598040 with 262144 loops 103 microseconds
cpucycles observed persecond 2507608832...2525190477 with 524288 loops 316 microseconds
cpucycles observed persecond 2583098522...2596502476 with 1048576 loops 405 microseconds

cfarm26, Intel Core i5-4570 in 32-bit mode under KVM, Debian 12.12, Linux kernel 6.1.0-41-686-pae:

cpucycles version 20260625
cpucycles tracesetup 0 x86-tsc precision 1018 scaling 1.000000 only32 0
cpucycles tracesetup 1 x86-tscasm precision 1028 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 731 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 3220 scaling 3.192606 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 4232 scaling 3192.606000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3192606000
cpucycles implementation default-perfevent
cpucycles iqm 779 +35-8+9+15+10-3-7-8-15+10+0-8+4+3-1-1+11+11-1+6+4-3-15-7+3-3+0-7+5+3-8+10+4+3+0-15-3-3-1-14-3+3+10-1-3-3-1-7+3-4+0+0-10+3-8+0+4-1+0-7+4+3-8+0
cpucycles observed persecond 283428571...1430400000 with 1024 loops 6 microseconds
cpucycles observed persecond 417142857...1240800000 with 2048 loops 6 microseconds
cpucycles observed persecond 715571428...1662000000 with 4096 loops 6 microseconds
cpucycles observed persecond 1132500000...2059666667 with 8192 loops 7 microseconds
cpucycles observed persecond 1568000000...2281333334 with 16384 loops 10 microseconds
cpucycles observed persecond 2254933333...2854769231 with 32768 loops 14 microseconds
cpucycles observed persecond 2658360000...3034000000 with 65536 loops 24 microseconds
cpucycles observed persecond 2174032786...2310118645 with 131072 loops 60 microseconds
cpucycles observed persecond 3329126582...3459415585 with 262144 loops 78 microseconds
cpucycles observed persecond 3455059210...3523140000 with 524288 loops 151 microseconds
cpucycles observed persecond 3454417763...3489394040 with 1048576 loops 303 microseconds

cfarm27, Intel Core i5-4570 in 32-bit mode under KVM, Alpine 3.19.9, Linux kernel 6.6.117-0-lts:

cpucycles version 20260625
cpucycles tracesetup 0 x86-tsc precision 1018 scaling 1.000000 only32 0
cpucycles tracesetup 1 x86-tscasm precision 1028 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 608 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 1601 scaling 3.192606 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 4232 scaling 3192.606000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3192606000
cpucycles implementation default-perfevent
cpucycles iqm 606 +72+2-9-3+2+6-4-2+2+2-6-3+5+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2+2+2-6-3+2+2-8-2
cpucycles observed persecond 356800000...1256666667 with 1024 loops 4 microseconds
cpucycles observed persecond 537400000...1404666667 with 2048 loops 4 microseconds
cpucycles observed persecond 787166666...1562500000 with 4096 loops 5 microseconds
cpucycles observed persecond 1261142857...2072000000 with 8192 loops 6 microseconds
cpucycles observed persecond 1890444444...2648714286 with 16384 loops 8 microseconds
cpucycles observed persecond 2392285714...2934250000 with 32768 loops 13 microseconds
cpucycles observed persecond 2879304347...3228952381 with 65536 loops 22 microseconds
cpucycles observed persecond 2723040816...2872978724 with 131072 loops 48 microseconds
cpucycles observed persecond 3326113924...3432428572 with 262144 loops 78 microseconds
cpucycles observed persecond 3386496774...3440797386 with 524288 loops 154 microseconds
cpucycles observed persecond 3202069696...3226439025 with 1048576 loops 329 microseconds

cfarm29, IBM POWER9, Debian 13.1, Linux kernel 6.12.57+deb13-powerpc64le:

cpucycles version 20260105
cpucycles tracesetup 0 ppc64-mftb precision 220 scaling 7.500000 only32 0
cpucycles tracesetup 1 default-perfevent precision 367 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 419 scaling 3.800000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 4130 scaling 3800.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3800000000
cpucycles implementation ppc64-mftb
cpucycles iqm 131 +26+27-4-3+4-4+4-3+4-4-3+11-3+4-4-3+4-4+4-3+4-4+4-3+4-4+4+4-3-4+4-3+4+11-3-11+4-4+4-3+4-4-3-4+12-4+4-3+4-11+4-4+4-3-4+12+4-11+4-4-3+4-4-3
cpucycles observed persecond 2535000000...5449000000 with 2048 loops 3 microseconds
cpucycles observed persecond 3042000000...5350000000 with 4096 loops 4 microseconds
cpucycles observed persecond 3244222222...4275000000 with 8192 loops 8 microseconds
cpucycles observed persecond 3587533333...4187846154 with 16384 loops 14 microseconds
cpucycles observed persecond 3714333333...3981290323 with 32768 loops 32 microseconds
cpucycles observed persecond 3693138888...3924264706 with 65536 loops 35 microseconds
cpucycles observed persecond 3795971428...3913897059 with 131072 loops 69 microseconds
cpucycles observed persecond 3821978417...3880839417 with 262144 loops 138 microseconds
cpucycles observed persecond 3821845323...3851086957 with 524288 loops 277 microseconds
cpucycles observed persecond 3835166064...3849797102 with 1048576 loops 553 microseconds

cfarm45, AMD Athlon II X4 640, Debian 8.11, Linux kernel 3.16.0-11-686-pae:

cpucycles version 20230105
cpucycles tracesetup 0 x86-tsc precision 199 scaling 1.000000 only32 0
cpucycles tracesetup 1 x86-tscasm precision 199 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 170 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 941 scaling 3.000000 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 3200 scaling 3000.000000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3000000000
cpucycles implementation default-perfevent
cpucycles median 72 +12+0+0+0+0+0+0+0+5+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+2+0+0+0+0+0+0+0+1+0+0+0+0+0+0
cpucycles observed persecond 541500000...1812000000 with 1024 loops 3 microseconds
cpucycles observed persecond 712333333...1212250000 with 2048 loops 5 microseconds
cpucycles observed persecond 1193285714...1733600000 with 4096 loops 6 microseconds
cpucycles observed persecond 1689176470...1804562500 with 8192 loops 33 microseconds
cpucycles observed persecond 1713074626...1770600000 with 16384 loops 66 microseconds
cpucycles observed persecond 1765107692...1795140625 with 32768 loops 129 microseconds
cpucycles observed persecond 1785369649...1800603922 with 65536 loops 256 microseconds
cpucycles observed persecond 1781377862...1796288462 with 131072 loops 261 microseconds
cpucycles observed persecond 1772647398...1778247827 with 262144 loops 691 microseconds
cpucycles observed persecond 1789670493...1794149598 with 524288 loops 870 microseconds
cpucycles observed persecond 1860276211...1861561332 with 1048576 loops 3156 microseconds

cfarm91, StarFive JH7100, Debian trixie/sid, Linux kernel 5.18.11-starfive:

cpucycles version 20250925
cpucycles tracesetup 0 riscv64-rdcycle precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 2702 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 1351 scaling 2.399988 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 2599 scaling 2399.987654 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation default-monotonic
cpucycles iqm 1476 +828-324+60+60+60+60-324+60-324+60+60-324+60+60-324+60+60-324+60-324+60+60-324+62-324+60+60-324+60+60-324+60-324+60+60-324+60+60-324+60-324+60+60-324+60+60-324+60-324+60+60+60+60+60-324+60-324+62+60+444+60-324+60+60
cpucycles observed persecond 1440250000...3968333334 with 1024 loops 7 microseconds
cpucycles observed persecond 1920181818...3072222223 with 2048 loops 10 microseconds
cpucycles observed persecond 2162473684...2733294118 with 4096 loops 18 microseconds
cpucycles observed persecond 2218777777...2530000000 with 8192 loops 35 microseconds
cpucycles observed persecond 2338014705...2490318182 with 16384 loops 67 microseconds
cpucycles observed persecond 2358559701...2440840910 with 32768 loops 133 microseconds
cpucycles observed persecond 2380905660...2419452472 with 65536 loops 264 microseconds
cpucycles observed persecond 2390815939...2410163810 with 131072 loops 526 microseconds
cpucycles observed persecond 2393901140...2403580953 with 262144 loops 1051 microseconds
cpucycles observed persecond 2397546190...2402577217 with 524288 loops 2099 microseconds
cpucycles observed persecond 2398864140...2401570967 with 1048576 loops 4327 microseconds

cfarm92, SiFive Freedom U740, Ubuntu 22.04.3, Linux kernel 5.19.0-1021-generic:

cpucycles version 20240114
cpucycles tracesetup 0 riscv64-rdcycle precision 8 scaling 1.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 2599 scaling 2.399988 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 2599 scaling 2399.987654 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation riscv64-rdcycle
cpucycles median 8 +168+20+2+2+0+0+0+0+570+0+0+0+0+0+0+0+144+0+0+0+0+0+0+0+160+0+0+0+0+0+0+0+160+0+0+0+0+0+0+0+154+0+0+0+0+0+0+0+154+0+0+0+0+0+0+0+152+0+0+0+0+0+0
cpucycles observed persecond 571500000...2198000000 with 1024 loops 3 microseconds
cpucycles observed persecond 833600000...2094000000 with 2048 loops 4 microseconds
cpucycles observed persecond 921888888...1445142858 with 4096 loops 8 microseconds
cpucycles observed persecond 1029625000...1320642858 with 8192 loops 15 microseconds
cpucycles observed persecond 1137034482...1284481482 with 16384 loops 28 microseconds
cpucycles observed persecond 1155701754...1227454546 with 32768 loops 56 microseconds
cpucycles observed persecond 1177464285...1217163637 with 65536 loops 111 microseconds
cpucycles observed persecond 1188018099...1207858448 with 131072 loops 220 microseconds
cpucycles observed persecond 1189925170...1200519363 with 262144 loops 440 microseconds
cpucycles observed persecond 1193962457...1199117446 with 524288 loops 878 microseconds
cpucycles observed persecond 1194051324...1196780111 with 1048576 loops 1811 microseconds

cfarm94, SiFive StarFive JH7110, Alpine 3.22.0_alpha20250108, Linux kernel 6.12.19-2-lts:

cpucycles version 20260625
cpucycles tracesetup 0 riscv64-perfrdcycle precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 riscv64-rdcycle precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 0 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 1750 scaling 1.500000 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 2510 scaling 1500.000000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1500000000
cpucycles implementation default-monotonic
cpucycles iqm 1125 +0+0+0-375+0+0+0+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0+0-375+0+0+1-375+0+0+0-375+0+0+0+0-375+0+0+0-375+0+0+0-375+0
cpucycles observed persecond 600000000...2500000000 with 1024 loops 4 microseconds
cpucycles observed persecond 875000000...2343750000 with 2048 loops 5 microseconds
cpucycles observed persecond 1083444444...1982285715 with 4096 loops 8 microseconds
cpucycles observed persecond 1258928571...1812500000 with 8192 loops 13 microseconds
cpucycles observed persecond 1312576923...1609458334 with 16384 loops 25 microseconds
cpucycles observed persecond 1412255319...1583355556 with 32768 loops 46 microseconds
cpucycles observed persecond 1451762376...1526545455 with 65536 loops 100 microseconds
cpucycles observed persecond 1487322033...1527891429 with 131072 loops 176 microseconds
cpucycles observed persecond 1490735537...1511465374 with 262144 loops 362 microseconds
cpucycles observed persecond 1493099573...1503243938 with 524288 loops 702 microseconds
cpucycles observed persecond 1497124823...1502417373 with 1048576 loops 1417 microseconds

cfarm95, SpacemiT X60, Debian trixie/sid, Linux kernel 6.6.36-cfarm #1:

cpucycles version 20260625
cpucycles tracesetup 0 riscv64-perfrdcycle precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 riscv64-rdcycle precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-perfevent precision 1794 scaling 1.000000 only32 0
cpucycles tracesetup 3 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-monotonic precision 1111 scaling 1.228800 only32 0
cpucycles tracesetup 5 default-gettimeofday precision 2248 scaling 1228.800000 only32 0
cpucycles tracesetup 6 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 1228800000
cpucycles implementation default-monotonic
cpucycles iqm 135 -33+19-32+172+19-33+18-33+19+19-32+888+19-33+19-32+18-33+19+224-33+18-33+19-32+19-33+377-33+19-33+18-31+18-33+428-32+19-33+18-33+19-32+633+19-33+18-33+19-32+19+376+18-31+18-33+19-33+18+19+19-32+19-33
cpucycles observed persecond 468000000...6052000000 with 1024 loops 6 microseconds
cpucycles observed persecond 962800000...2696333334 with 2048 loops 4 microseconds
cpucycles observed persecond 1043250000...1476166667 with 4096 loops 7 microseconds
cpucycles observed persecond 1102600000...1311461539 with 8192 loops 14 microseconds
cpucycles observed persecond 1175785714...1285923077 with 16384 loops 27 microseconds
cpucycles observed persecond 1198090909...1253943397 with 32768 loops 54 microseconds
cpucycles observed persecond 1214266055...1246056075 with 65536 loops 108 microseconds
cpucycles observed persecond 1217488479...1237860466 with 131072 loops 216 microseconds
cpucycles observed persecond 1224293023...1233245328 with 262144 loops 429 microseconds
cpucycles observed persecond 1225245348...1230967366 with 524288 loops 859 microseconds
cpucycles observed persecond 1227769590...1230615926 with 1048576 loops 1709 microseconds

cfarm103, Apple M1 (Icestorm-M1 + Firestorm-M1), Debian trixie/sid, Linux kernel 6.5.0-asahi-00780-g62806c2c6f29:

cpucycles version 20260625
cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1086 scaling 86.000000 only32 0
cpucycles tracesetup 3 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1094 scaling 2.064000 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 3084 scaling 2064.000000 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2064000000
cpucycles implementation arm64-vct
cpucycles iqm 0 +0+0+0+86+0+0+0+0+258+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+0+86+0+0+0+0+0+0+0+86+0+0+0
cpucycles observed persecond 1311500000...2709000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1748666666...2666000000 with 8192 loops 5 microseconds
cpucycles observed persecond 1834666666...2383428572 with 16384 loops 8 microseconds
cpucycles observed persecond 2053250000...2358857143 with 32768 loops 15 microseconds
cpucycles observed persecond 1988424242...2122258065 with 65536 loops 32 microseconds
cpucycles observed persecond 2017692307...2084476191 with 131072 loops 64 microseconds
cpucycles observed persecond 2050129032...2078052288 with 262144 loops 154 microseconds
cpucycles observed persecond 2056833333...2071818182 with 524288 loops 287 microseconds
cpucycles observed persecond 2060477815...2067828768 with 1048576 loops 585 microseconds

cfarm104, Apple M1 (Icestorm-M1 + Firestorm-M1), MacOSX 12.6 21.6.0:

cpucycles version 20251226
cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 200 scaling 100.000000 only32 0
cpucycles tracesetup 3 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 4 default-mach precision 200 scaling 100.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 2699 scaling 2.399988 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 2699 scaling 2399.987654 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation arm64-vct
cpucycles iqm 0 +4500+0+0+0+0+0+100+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+100+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+100+0+0+0+0+0+0+0
cpucycles observed persecond 1725000000...3450000000 with 8192 loops 3 microseconds
cpucycles observed persecond 1885714285...2640000000 with 16384 loops 6 microseconds
cpucycles observed persecond 2300000000...2533333334 with 32768 loops 22 microseconds
cpucycles observed persecond 2339285714...2523076924 with 65536 loops 27 microseconds
cpucycles observed persecond 2348529411...2421212122 with 131072 loops 67 microseconds
cpucycles observed persecond 2377678571...2420909091 with 262144 loops 111 microseconds
cpucycles observed persecond 2387214611...2410138249 with 524288 loops 218 microseconds
cpucycles observed persecond 2397814207...2411813187 with 1048576 loops 365 microseconds

cfarm110 (gcc1-power7), IBM POWER7, CentOS 7.9 AltArch, Linux kernel 3.10.0-1160.105.1.el7.ppc64:

cpucycles version 20260105
cpucycles tracesetup 0 ppc64-mftb precision 212 scaling 7.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 236 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 465 scaling 3.550000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 3880 scaling 3550.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3550000000
cpucycles implementation ppc64-mftb
cpucycles iqm 167 +36-34+36-34-13+15-20+22-27+29-41+43-48+36-41+36-34+22-20+15-13+8-6-6+8-13+15-20+22-34+36+15-13+8-6+1+1-13+15-20+22-34+36-48+36-41+8-6+36-34+22-20+15-13+8-6-6+8-20+22-27+29-41+36
cpucycles observed persecond 3159333333...4905250000 with 4096 loops 5 microseconds
cpucycles observed persecond 3386727272...4216333334 with 8192 loops 10 microseconds
cpucycles observed persecond 3348333333...3739842106 with 16384 loops 20 microseconds
cpucycles observed persecond 3534829268...3733153847 with 32768 loops 40 microseconds
cpucycles observed persecond 3473016129...3599166667 with 65536 loops 61 microseconds
cpucycles observed persecond 3541000000...3609900000 with 131072 loops 111 microseconds
cpucycles observed persecond 3571450450...3606177273 with 262144 loops 221 microseconds
cpucycles observed persecond 3578959367...3596333334 with 524288 loops 442 microseconds
cpucycles observed persecond 3578793453...3587492082 with 1048576 loops 885 microseconds

cfarm112 (gcc2-power8), IBM POWER8E, CentOS 7.9 AltArch, Linux kernel 3.10.0-1127.13.1.el7.ppc64le:

cpucycles version 20260625
cpucycles tracesetup 0 ppc64-mftb precision 1159 scaling 7.250000 only32 0
cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 1342 scaling 3.690000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 4710 scaling 3690.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3690000000
cpucycles implementation ppc64-mftb
cpucycles iqm 194 +9-6-5+1-5+9-6+9-12+1+9+2+2+2+9-13+2+16-13-5+1+2+2-6+17-6-5+9-6-5+1+2+9+2+9-6-5+16-5+1-5+9+2+1+2-13+9+9-5-6+9+2-5+1-5+9-6+17-6-13+9+9-5+2
cpucycles observed persecond 2802000000...9240500000 with 1024 loops 3 microseconds
cpucycles observed persecond 2977714285...4412200000 with 2048 loops 6 microseconds
cpucycles observed persecond 3208083333...3927300000 with 4096 loops 11 microseconds
cpucycles observed persecond 3486608695...3855952381 with 8192 loops 22 microseconds
cpucycles observed persecond 3606500000...3832027778 with 16384 loops 37 microseconds
cpucycles observed persecond 3644816666...3781258621 with 32768 loops 59 microseconds
cpucycles observed persecond 3672697478...3740752137 with 65536 loops 118 microseconds
cpucycles observed persecond 3687067510...3721102128 with 131072 loops 236 microseconds
cpucycles observed persecond 3702415254...3719497873 with 262144 loops 471 microseconds
cpucycles observed persecond 3705988335...3714527099 with 524288 loops 942 microseconds
cpucycles observed persecond 3708108821...3712812798 with 1048576 loops 1892 microseconds

cfarm120, IBM POWER10, AlmaLinux 9.7, Linux kernel 5.14.0-427.31.1.el9_4.ppc64le:

cpucycles version 20260625
cpucycles tracesetup 0 ppc64-mftb precision 1023 scaling 5.750000 only32 0
cpucycles tracesetup 1 default-perfevent precision 139 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 1046 scaling 2.950000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 3980 scaling 2950.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2950000000
cpucycles implementation default-perfevent
cpucycles iqm 136 +45+44+0+1+2+1+0+0+0+0+0+5+2+1+3+0+0+1+1+14+1+0+1+0+0+2+0+0+0+2+0+0+0+14+0+0+1+0+1+2+1+0+0+14+0+1+0+14+1+0+1+0+0+1+3+0+1+2+0+0+0+0+0+1
cpucycles observed persecond 1811000000...3992000000 with 2048 loops 3 microseconds
cpucycles observed persecond 2836600000...4901333334 with 4096 loops 4 microseconds
cpucycles observed persecond 2868444444...3754428572 with 8192 loops 8 microseconds
cpucycles observed persecond 3355777777...3810062500 with 16384 loops 17 microseconds
cpucycles observed persecond 3409464285...3692000000 with 32768 loops 27 microseconds
cpucycles observed persecond 3736972222...3969617648 with 65536 loops 35 microseconds
cpucycles observed persecond 3785605633...3901246377 with 131072 loops 70 microseconds
cpucycles observed persecond 3830314285...3888688406 with 262144 loops 139 microseconds
cpucycles observed persecond 3873345323...3902855073 with 524288 loops 277 microseconds
cpucycles observed persecond 3884176795...3899293901 with 1048576 loops 542 microseconds

cfarm185, Ampere eMAG 8180, AlmaLinux 8.10, Linux kernel 4.18.0-553.el8_10.aarch64:

cpucycles version 20260625
cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1075 scaling 75.000000 only32 0
cpucycles tracesetup 3 default-perfevent precision 205 scaling 1.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1167 scaling 3.000000 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 4030 scaling 3000.000000 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3000000000
cpucycles implementation default-perfevent
cpucycles iqm 264 -25-16-17+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 890000000...4520500000 with 1024 loops 3 microseconds
cpucycles observed persecond 1082000000...1897250000 with 2048 loops 5 microseconds
cpucycles observed persecond 1811000000...2751800000 with 4096 loops 6 microseconds
cpucycles observed persecond 2257272727...2859777778 with 8192 loops 10 microseconds
cpucycles observed persecond 2607736842...2970588236 with 16384 loops 18 microseconds
cpucycles observed persecond 2901970588...3114531250 with 32768 loops 33 microseconds
cpucycles observed persecond 3028430769...3138857143 with 65536 loops 64 microseconds
cpucycles observed persecond 3074007812...3128968254 with 131072 loops 127 microseconds
cpucycles observed persecond 3121726190...3149980000 with 262144 loops 251 microseconds
cpucycles observed persecond 3127475149...3141540919 with 524288 loops 502 microseconds
cpucycles observed persecond 3142828171...3149926927 with 1048576 loops 1000 microseconds

cfarm202, UltraSparc T5, Debian forky/sid, Linux kernel 6.17.0-rc5+:

cpucycles version 20260625
cpucycles tracesetup 0 sparc64-rdtick precision 65 scaling 1.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 448 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 1235 scaling 3.599910 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 4629 scaling 3599.910000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 3599910000
cpucycles implementation sparc64-rdtick
cpucycles iqm 73 +24+0+24+24+24+0+0+24+0+0+1+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 2888000000...4979666667 with 4096 loops 4 microseconds
cpucycles observed persecond 3197777777...4196285715 with 8192 loops 8 microseconds
cpucycles observed persecond 3380235294...3863000000 with 16384 loops 16 microseconds
cpucycles observed persecond 3479030303...3719000000 with 32768 loops 32 microseconds
cpucycles observed persecond 3530707692...3650428572 with 65536 loops 64 microseconds
cpucycles observed persecond 3584937500...3645658731 with 131072 loops 127 microseconds
cpucycles observed persecond 3584468750...3614586615 with 262144 loops 255 microseconds
cpucycles observed persecond 3591248532...3606304519 with 524288 loops 510 microseconds
cpucycles observed persecond 3594648383...3602175663 with 1048576 loops 1020 microseconds

cfarm216, VM on SPARC-M8, Solaris 11.4.88.207.1:

cpucycles version 20260105
cpucycles tracesetup 0 sparc64-rdtick precision 63 scaling 1.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 614 scaling 5.067000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 5387 scaling 5067.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 5067000000
cpucycles implementation sparc64-rdtick
cpucycles iqm 69 +0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+57376+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 2865000000...5940000000 with 4096 loops 3 microseconds
cpucycles observed persecond 4597800000...7831000000 with 8192 loops 4 microseconds
cpucycles observed persecond 4558600000...5760750000 with 16384 loops 9 microseconds
cpucycles observed persecond 4765578947...5356647059 with 32768 loops 18 microseconds
cpucycles observed persecond 4794418604...5041268293 with 65536 loops 42 microseconds
cpucycles observed persecond 4968216216...5114986112 with 131072 loops 73 microseconds
cpucycles observed persecond 4965598484...5044946154 with 262144 loops 131 microseconds
cpucycles observed persecond 4984102661...5023766284 with 524288 loops 262 microseconds
cpucycles observed persecond 4985677238...5005539326 with 1048576 loops 535 microseconds

cfarm230, Cavium Octeon III V0.2, Debian 10.13, Linux kernel 4.9.79-UBNT_E300:

cpucycles version 20260625
cpucycles tracesetup 0 mips64-cc precision 323 scaling 1.000000 only32 1
cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 2243 scaling 2.399988 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 3419 scaling 2399.987654 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation mips64-cc
cpucycles iqm 405 +30+17+6+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
cpucycles observed persecond 868444444...1931285715 with 1024 loops 8 microseconds
cpucycles observed persecond 923437500...1160571429 with 2048 loops 15 microseconds
cpucycles observed persecond 969766666...1089250000 with 4096 loops 29 microseconds
cpucycles observed persecond 979067796...1037964913 with 8192 loops 58 microseconds
cpucycles observed persecond 983837606...1013113044 with 16384 loops 116 microseconds
cpucycles observed persecond 994792207...1009589520 with 32768 loops 230 microseconds
cpucycles observed persecond 996036876...1003851852 with 65536 loops 460 microseconds
cpucycles observed persecond 998830250...1002534352 with 131072 loops 918 microseconds
cpucycles observed persecond 998601196...1000898149 with 262144 loops 1837 microseconds
cpucycles observed persecond 999575323...1000699892 with 524288 loops 3703 microseconds
cpucycles observed persecond 999797523...1000292365 with 1048576 loops 7348 microseconds

cfarm400, Loongson-3C5000L-LL, Debian trixie/sid, Linux kernel 6.1.0-rc7+:

cpucycles version 20260105
cpucycles tracesetup 0 loong64-rdtime precision 124 scaling 24.000000 only32 0
cpucycles tracesetup 1 default-perfevent precision 180 scaling 1.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 416 scaling 2.399988 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 2729 scaling 2399.987654 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation loong64-rdtime
cpucycles iqm 48 +24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+24+0+0+0+0+0+0+0
cpucycles observed persecond 1982400000...3408000000 with 4096 loops 4 microseconds
cpucycles observed persecond 1975200000...2514000000 with 8192 loops 9 microseconds
cpucycles observed persecond 2190666666...2482500000 with 16384 loops 17 microseconds
cpucycles observed persecond 2315294117...2469000000 with 32768 loops 33 microseconds
cpucycles observed persecond 2348776119...2425846154 with 65536 loops 66 microseconds
cpucycles observed persecond 2383636363...2422892308 with 131072 loops 131 microseconds
cpucycles observed persecond 2392425855...2411954023 with 262144 loops 262 microseconds
cpucycles observed persecond 2392334600...2402061069 with 524288 loops 525 microseconds
cpucycles observed persecond 2396822857...2401694657 with 1048576 loops 1049 microseconds

cfarm425, Ampere Altra Max M128-30, Debian forky, Linux kernel 6.16.12+deb14+1-arm64:

cpucycles version 20260625
cpucycles tracesetup 0 arm64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 arm64-pmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 arm64-vct precision 1096 scaling 96.000000 only32 0
cpucycles tracesetup 3 default-perfevent precision 91 scaling 1.000000 only32 0
cpucycles tracesetup 4 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 5 default-monotonic precision 1116 scaling 2.399988 only32 0
cpucycles tracesetup 6 default-gettimeofday precision 3429 scaling 2399.987654 only32 0
cpucycles tracesetup 7 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation default-perfevent
cpucycles iqm 82 +29-1-1-1-1-1+386-1-1-1+179-1-1+130+161-1+235-1-1-1-1+153+170-1-1+149-1-1-1+258+154-1-1-1-1-1-1-1-1-1-1+196+194-1+172-1-1-1-1-1-1-1+158-1-1+183-1-1-1-1-1-1-1+235
cpucycles observed persecond 547750000...1263500000 with 2048 loops 3 microseconds
cpucycles observed persecond 852200000...1532333334 with 4096 loops 4 microseconds
cpucycles observed persecond 1412166666...2203250000 with 8192 loops 5 microseconds
cpucycles observed persecond 1822600000...2320375000 with 16384 loops 9 microseconds
cpucycles observed persecond 2064187500...2383285715 with 32768 loops 15 microseconds
cpucycles observed persecond 2266612903...2434482759 with 65536 loops 30 microseconds
cpucycles observed persecond 2322280701...2412890910 with 131072 loops 56 microseconds
cpucycles observed persecond 2391572727...2438981482 with 262144 loops 109 microseconds
cpucycles observed persecond 2413564220...2437481482 with 524288 loops 217 microseconds
cpucycles observed persecond 2432299539...2444340278 with 1048576 loops 433 microseconds

cfarm430, AMD EPYC 7773X, FreeBSD 16.0 VM:

cpucycles version 20260625
cpucycles tracesetup 0 amd64-perfpmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 1 amd64-perfpmc precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 amd64-pmcff precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 amd64-tsc precision 1022 scaling 1.000000 only32 0
cpucycles tracesetup 4 amd64-tscasm precision 1032 scaling 1.000000 only32 0
cpucycles tracesetup 5 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 6 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 7 default-monotonic precision 1140 scaling 2.399988 only32 0
cpucycles tracesetup 8 default-gettimeofday precision 3429 scaling 2399.987654 only32 0
cpucycles tracesetup 9 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 2399987654
cpucycles implementation amd64-tsc
cpucycles iqm 26 +40-4-4+18-4-4+150+18-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4-4+18-4-4+18-4-4+18-4-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4+18-4-4-4+18-4-4+18-4+18-4-4+18-4-4
cpucycles observed persecond 1578500000...3322000000 with 4096 loops 3 microseconds
cpucycles observed persecond 1782000000...2569600000 with 8192 loops 6 microseconds
cpucycles observed persecond 2053333333...2503600000 with 16384 loops 11 microseconds
cpucycles observed persecond 2053040000...2245913044 with 32768 loops 24 microseconds
cpucycles observed persecond 2189423076...2283600000 with 65536 loops 51 microseconds
cpucycles observed persecond 2179614678...2224467290 with 131072 loops 108 microseconds
cpucycles observed persecond 2189704433...2216746269 with 262144 loops 202 microseconds
cpucycles observed persecond 2195588235...2211413979 with 524288 loops 373 microseconds
cpucycles observed persecond 2196466750...2203708177 with 1048576 loops 796 microseconds

z15, IBM z15:

cpucycles version 20230106
cpucycles tracesetup 0 s390x-stckf precision 250 scaling 1.269531 only32 0
cpucycles tracesetup 1 default-perfevent precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 2 default-mach precision 0 scaling 0.000000 only32 0
cpucycles tracesetup 3 default-monotonic precision 272 scaling 5.200000 only32 0
cpucycles tracesetup 4 default-gettimeofday precision 5400 scaling 5200.000000 only32 0
cpucycles tracesetup 5 default-zero precision 0 scaling 0.000000 only32 0
cpucycles persecond 5200000000
cpucycles implementation s390x-stckf
cpucycles median 48 +87+8+0-2+0+0+38-2+0+1-3+1+28+0+3-3+1+0+28+0-2+3+0-2+36+0+0+0+1+0+28+0-2+0+3-2+35+1+0-2+0+3+28+0-2+0+0-2+3+25+3+0-2+0+1+35+1+0+0-2+0+28+0
cpucycles observed persecond 4948941176...5627733334 with 8192 loops 16 microseconds
cpucycles observed persecond 4104125000...5515666667 with 16384 loops 7 microseconds
cpucycles observed persecond 5047076923...5987818182 with 32768 loops 12 microseconds
cpucycles observed persecond 5044846153...5475708334 with 65536 loops 25 microseconds
cpucycles observed persecond 5141313725...5357428572 with 131072 loops 50 microseconds
cpucycles observed persecond 5150892156...5257250000 with 262144 loops 101 microseconds
cpucycles observed persecond 5183421568...5236549505 with 524288 loops 203 microseconds
cpucycles observed persecond 5190282555...5216582717 with 1048576 loops 406 microseconds

Version: This is version 2026.09.01 of the "Counters" web page.
libcpucycles-20260901/doc/html/download.html0000444000000000000000000003021215245636444017355 0ustar rootroot libcpucycles: Download
libcpucycles: Download

To download and unpack the latest version of libcpucycles:

wget -m https://cpucycles.cr.yp.to/libcpucycles-latest-version.txt
version=$(cat cpucycles.cr.yp.to/libcpucycles-latest-version.txt)
wget -m https://cpucycles.cr.yp.to/libcpucycles-$version.tar.gz
tar -xzf cpucycles.cr.yp.to/libcpucycles-$version.tar.gz
cd libcpucycles-$version

Then install.

Archives and changelog (reverse chronological)

libcpucycles-20260901.tar.gz browse

In amd64-perfpmcff and default-perfevent, use /sys/bus/event_source/devices/cpu_atom/type for the PMU type for Intel E-cores. This is observed to handle, e.g., Alder Lake E-cores with PMU type 8.

Skip amd64-perfpmcff for PMC version <3 or for PMC width <48. This avoids a wraparound observed under Debian on two Core 2 CPUs from 2007 and 2009. (Those CPUs have PMC version 2 and PMC width 40. The observed wraparound is at 31 bits rather than 40 bits, presumably from continual usage of wrmsr by the OS.) Falling back to default-perfevent adds about 200 cycles to each cycle count on those CPUs, and adds about 500 cycles to each cycle count on an Airmont CPU from 2015.

Adjust auto-generation scripts to auto-generate wrapper version and to avoid some Python 3.13 warnings.


libcpucycles-20260625.tar.gz browse

In amd64-perfpmcff and default-perfevent, to compensate for the Linux kernel not doing what the perf_event_open manual page promises, try opening a second fd using PMU type 10 for Intel E-cores. This should prevent fallbacks to tsc for programs pinned to E-cores, and should let cycle counting continue for programs that migrate from P-cores to E-cores.

Clear /proc/sys/kernel/nmi_watchdog in cpucycles-open. Otherwise the Linux NMI watchdog forces a wraparound after some number of seconds in RDPMC cycle counts from amd64-perfpmcff, corrupting multi-second cycle counts on Intel machines. AMD machines are unaffected.

Increase bump to 1000 for all off-core counters and fixed-frequency counters.


libcpucycles-20260105.tar.gz browse

Bigger split of RDPMC-based counters to handle not just perf sometimes incorrectly returning index 0 on Intel but also AMD not supporting fixed-function counter 0x40000001. New amd64-perfpmcff tries fixed-function counter 0x40000001 within perf; amd64-perfpmc now goes back to trying index returned by perf; amd64-pmcff (renamed from amd64-pmc) tries fixed-function counter 0x40000001 outside perf.

Add orderbump mechanism, for example to prefer tsc more systematically over tscasm.


libcpucycles-20251226.tar.gz browse

Split amd64-pmc, arm64-pmc, riscv32-rdcycle, and riscv64-rdcycle into perf and non-perf versions, with the perf versions tried first. Hopefully the perf versions will also eliminate the need to install kernel modules for amd64-pmc and arm64-pmc.

For amd64-pmc, always use fixed-function cycle counter (1<<30)|1. This works around a bug in, e.g., kernel 6.1.0 perf incorrectly returning index 0 for E-cores.

For all perf-based counters, use PERF_FLAG_FD_CLOEXEC if it is available.

For *tsc* counters, return invariant TSC frequency if that is clear from CPUID information. Thanks to Tee-Kiah Chia for the suggestion and a prototype patch.

Add internal ticks_close(), most importantly for closing perf descriptors. (An alternative would be to unify the perf handling inside a single perf_event_open in wrapper conditioned on Linux, but this raises the question of how to handle perf platform variations such as arm64-pmc needing 3 in config1.)

Increase penalty for EXTEND32 counters. (It might be better to directly benchmark the extension.)

Increase penalty for fixed-frequency counters, including RDTSC when it is known to be invariant.

For wrapper, use sigjmp_buf instead of jmp_buf.

Document requirements on /sys/devices/cpu*/rdpmc and /proc/sys/kernel/perf_user_access. Add cpucycles-open abstraction.

Update configure: recognize a few more x86 synonyms; --no- instead of --no; support configure.log.

Support $DESTDIR in install. Thanks to Robert Clausecker for the suggestion.


libcpucycles-20250925.tar.gz browse

For perfevent, try all combinations of disabling exclude-kernel and disabling exclude-hv, to handle platforms where cycle counters cannot handle one or both of those.

For perfevent, do DISABLE and ENABLE around counter read (suggested by Jim Apple) to (hopefully) handle Graviton 3. But skip this if a setup test seems to work without it.

Recognize sun4v as sparc64.

Add support for loong64.

Eliminate various compiler warnings.

For cpucycles-info, print interquartile mean (iqm) rather than median.

Say "sometimes" in documentation for enabling cycle counters in ARM via kernel modules.

Change HTML style, in particular for better usability on phones.


libcpucycles-20240318.tar.gz browse

Port to MacOS X: handle missing -lrt, and handle differences in shared-library naming.

Include cpucycles-info man page.


libcpucycles-20240114.tar.gz browse

Add arm32-1176 counter.

Allow slop 0.2 rather than 0.1 for FINDMULTIPLIER.

Improve platform detection.

Port to FreeBSD.

Use blue boldface during compilation for "skipping option that did not compile".

doc/install.md: headings; note manual pages.

Add doc/license.md.

Update HTML style for better tt visibility and copy-paste.


libcpucycles-20230115.tar.gz browse

Update actual cpucycles_version behavior to match documentation.


libcpucycles-20230110.tar.gz browse

doc/api.md: Document cpucycles_version().

Add s390x-stckf counter.

cpucycles/default-perfevent.c: Read into int64_t instead of long long. Add comment explaining issues with PERF_FORMAT_TOTAL_TIME_RUNNING.

configure: Improve uname handling.

doc/api.md: Update description of default frequency.


libcpucycles-20230105.tar.gz browse

Initial release.


Version: This is version 2026.09.01 of the "Download" web page.
libcpucycles-20260901/doc/html/index.html0000444000000000000000000001442015245636444016660 0ustar rootroot libcpucycles: Intro
libcpucycles: Intro

libcpucycles is a microlibrary for counting CPU cycles. Cycle counts are not as detailed as Falk diagrams but are the most precise timers available to typical software; they are central tools used in understanding and improving software performance.

The libcpucycles API is simple: include <cpucycles.h>, call cpucycles() to receive a long long whenever desired, and link with -lcpucycles.

Internally, libcpucycles understands machine-level cycle counters for amd64 (both PMC and TSC), arm32, arm64 (both PMC and VCT), loong64, mips64, ppc32, ppc64, riscv32, riscv64, s390x, sparc64, and x86. libcpucycles also understands four OS-level mechanisms, which give varying levels of accuracy: mach_absolute_time, perf_event, CLOCK_MONOTONIC, and, as a fallback, microsecond-resolution gettimeofday.

When the program first calls cpucycles(), libcpucycles automatically benchmarks the available mechanisms and selects the mechanism that does the best job. Subsequent cpucycles() calls are thread-safe and very fast. An accompanying cpucycles-info program prints a summary of cycle-counter accuracy.

For comparison, there is a simple-sounding __rdtsc() API provided by compilers, but this works only on Intel/AMD CPUs and is generally noisier than PMC. There is a __builtin_readcyclecounter() that works on more CPUs, but this works only with clang and has the same noise problems. Both of these mechanisms put the burden on the caller to figure out what can be done on other CPUs. Various packages include their own more portable abstraction layers for counting cycles (see, e.g., FFTW's cycle.h, used to automatically select from among multiple implementations provided by FFTW), but this creates per-package effort to keep up with the latest cycle counters. The goal of libcpucycles is to provide state-of-the-art cycle counting centrally for all packages to use.

Latest release: 20260901.


Version: This is version 2026.09.01 of the "Intro" web page.
libcpucycles-20260901/doc/html/install.html0000444000000000000000000001570415245636444017225 0ustar rootroot libcpucycles: Install
libcpucycles: Install

Prerequisites:

  • python3 (for: build)
  • gcc and/or clang (for: build)

Currently tested only under Linux, but porting to other systems shouldn't be difficult.

For sysadmins

To install in /usr/local/{include,lib,bin,man}:

./configure && make -j8 install

For developers with an unprivileged account

Typically you'll already have

export LD_LIBRARY_PATH="$HOME/lib"
export LIBRARY_PATH="$HOME/lib"
export CPATH="$HOME/include"
export MANPATH="$HOME/man"
export PATH="$HOME/bin:$PATH"

in $HOME/.profile. To install in $HOME/{include,lib,bin,man}:

./configure --prefix=$HOME && make -j8 install

For distributors creating a package

Run

./configure --prefix=/usr && make -j8

and then follow your usual packaging procedures for the build/0/package files:

build/0/package/man/man3/cpucycles.3
build/0/package/include/cpucycles.h
build/0/package/lib/libcpucycles*
build/0/package/bin/cpucycles-info
build/0/package/bin/cpucycles-open

There are some old systems where libcpucycles requires -lrt for clock_gettime; currently libcpucycles.so doesn't link to -lrt, so it's up to the caller to link to -lrt.

You may wish to provide a package that runs cpucycles-open on each boot, but this should be separate from the main cpucycles package: cpucycles is functional without cpucycles-open, and some security policies are contrary to cpucycles-open.

More options

You can run

./configure --host=amd64

to override ./configure's guess of the architecture that it should compile for. The architecture controls which cycle counters to try compiling: e.g., amd64 tries compiling cpucycles/amd64* and cpucycles/default*.

Inside the build directory, 0 is symlinked to amd64 for --host=amd64. Running make clean removes build/amd64. Re-running ./configure automatically starts with make clean.

A subsequent ./configure --host=arm64 will create build/arm64 and symlink 0 -> arm64, without touching an existing build/amd64. However, cross-compilers aren't yet selected automatically.

Compilers tried are listed in compilers/default. Each compiler includes -fPIC to create a shared library, -fvisibility=hidden to hide non-public symbols in the library, and -fwrapv to switch to a slightly less dangerous version of C. The first compiler that seems to work is used to compile everything.


Version: This is version 2026.06.25 of the "Install" web page.
libcpucycles-20260901/doc/html/license.html0000444000000000000000000001055215245636444017175 0ustar rootroot libcpucycles: License
libcpucycles: License

libcpucycles is hereby placed into the public domain.

SPDX-License-Identifier: LicenseRef-PD-hp OR CC0-1.0 OR 0BSD OR MIT-0 OR MIT


Version: This is version 2024.01.14 of the "License" web page.
libcpucycles-20260901/doc/html/security.html0000444000000000000000000002223115245636444017417 0ustar rootroot libcpucycles: Security
libcpucycles: Security

Timing attacks

Many security systems have been shown to be breakable by "timing attacks". These attacks extract secrets by analyzing timings of the legitimate user's operations on secret data. See the June 2022 survey page https://timing.attacks.cr.yp.to for an overview and further references.

Sometimes these attacks are used as motivation to disable the attacker's access to various timing mechanisms. For example, Firefox rounds its performance.now timer to 1-millisecond resolution "to mitigate potential security threats".

As another example, reducing /proc/sys/kernel/perf_event_paranoid under Linux to 2 (from 3 or higher), so that libcpucycles has access to the best available Intel/AMD cycle counter (RDPMC), also means making this cycle counter and other performance-monitoring counters available to any attacker-controlled software running on the computer. Perhaps this helps timing attacks, not to mention the possibility of opening up other vulnerabilities via the complicated perf_event interface.

As yet another example, ARM CPUs disable user access to the main CPU cycle counter by default. Allowing user access to the cycle counter (via a kernel module or other kernel configuration) could help attacks.

Given the availability of simple mechanisms to disable RDPMC etc., it is easy to recommend using those mechanisms. To avoid creating unnecessary tension between those recommendations and the use of libcpucycles, applications that use libcpucycles should be structured so that high-resolution timers are used only on controlled development and benchmarking machines, not on general end-user machines.

This structure might seem incompatible with using cycle counts to automatically select the best of multiple options, as in FFTW. However, infrastructure introduced in lib25519 automatically selects options on end-user machines based on cycle counts that were collected on benchmarking machines.

The above text should not be understood as endorsing the idea that disabling timers is an effective defense against timing attacks. Certainly disabling high-resolution timers is not sufficient for security: there are many ways for attackers to amplify timing signals and to statistically filter out noise from low-resolution timers. Disabling every standard timing mechanism on the machine does not stop the attacker from accessing a remote timer or a counter maintained by the attacker's software. Perhaps disabling timers sometimes makes the difference between a feasible attack and an infeasible attack, but evaluating this is extremely difficult.

Meanwhile there is an auditable methodology available to stop timing attacks: constant-time programming, which systematically cuts off data flow from secrets to timings.

For example, constant-time programming does not permit comparisons involving secrets (e.g., x>y where x or y is secret): comparisons are sometimes compiled into branches, and branches take variable time. The cryptoint library provides constant-time comparison operations.

As another example, constant-time programming disables overclocking mechanisms such as Turbo Boost: secrets affect a CPU's power consumption, and overclocking creates data flow from power consumption to timings. The importance of disabling overclocking is illustrated by the Hertzbleed attack extracting secret keys from the SIKE cryptosystem (before SIKE was broken in other ways), and by an independent attack extracting secret AES keys. This is why https://timing.attacks.cr.yp.to recommends turning off Turbo Boost "right now", and explains the mechanisms available to do this. One non-security reason that it was already normal (although not universal) for manufacturers to provide these mechanisms to end users is that Turbo Boost has a reputation for causing premature hardware failures. Turbo Boost also provides very little speed benefit for modern multithreaded vectorized applications.

Another reaction to timing attacks is to apply "masking" techniques. These techniques seem to make it more difficult for attackers to extract secrets from power consumption and other side channels. However, as https://timing.attacks.cr.yp.to explains, it is "practically impossible for an auditor to obtain any real assurance that these techniques are secure". See the paper "Breaking a fifth-order masked implementation of CRYSTALS-Kyber by copy-paste" for an example of a security failure in a masked implementation.

Setuid programs

libcpucycles is not intended for usage in setuid programs. It often calls further programs to estimate the CPU frequency, and it inspects possibly untrustworthy environment variables.


Version: This is version 2026.06.25 of the "Security" web page.
libcpucycles-20260901/doc/html/selection.html0000444000000000000000000002602715245636444017544 0ustar rootroot libcpucycles: Selection
libcpucycles: Selection

Here is how libcpucycles decides which cycle counter to use. The underlying principles are as follows:

  • Failure is not allowed. Using a low-resolution timer such as gettimeofday() to estimate cycle counts is not desirable but is better than providing no information.

  • A counter that does well on some CPUs and OSes can do badly on others. The counter selection in libcpucycles is based not just on rules set at compile time but also on measurements of how well the counters perform when the program first calls cpucycles().

  • A critical application of cycle counting is collecting cycle counts for multiple options to see which option is faster. It is the caller's responsibility, given cycle counts for many runs of whichever function is being benchmarked, to compute robust statistics such as stabilized quartiles, so as to filter out occasional cycle-count jumps caused by migration to another core (if the benchmark is not pinned to a single core) or by interrupts from other OS activity, not to mention intrinsic variations in the function's run time. libcpucycles does not reject an otherwise attractive counter merely because of occasional jumps.

  • Cycle-counting overhead is not desirable, but does not directly affect comparisons of multiple options measured using the same cycle counter, so it is less important than consistent major errors such as treating 232 + x cycles as x cycles. (Performance experts seeing a function that takes billions of cycles usually focus on smaller subroutines, but libcpucycles should not break larger measurements.) This is why libcpucycles does not provide direct access to 32-bit cycle counters: it provides wrappers that combine the counters with gettimeofday() to produce 64 bits, even though this incurs some extra overhead.

  • The noise introduced by typical off-core clocks, such as multiplying a 24MHz clock by 86 to estimate cycles on a 2.064GHz CPU core, comes in small part from low resolution but much more from changes in CPU frequency: e.g., a 10000-cycle computation might be measured as 20000 cycles when the CPU enters a power-saving mode. When libcpucycles has access to what is believed to be an on-core cycle counter, it uses that even when its measurements show some noise. (Choosing an on-core cycle counter does not magically eliminate the change in the relative speed of the CPU and DRAM; the usual advice to warm up the CPU and set constant frequencies if possible still applies.)

When cpucycles() is first called, libcpucycles tries running each cycle counter that has been compiled into the library. For example, for 64-bit ARM CPUs, libcpucycles will try arm64-pmc, arm64-vct, default-gettimeofday, default-mach, default-monotonic, and default-perfevent, minus any of those that failed to compile.

Cycle counters that fail at run time with SIGILL (or SIGFPE or SIGBUS or SIGSEGV or SIGABRT) are eliminated from the list. For example, arm64-pmc will fail with SIGILL if the kernel does not allow user access to PMCCNTR_EL0. Beware that libcpucycles does not catch SIGILL after its initial tests: if the kernel initially allows user access to PMCCNTR_EL0 but later turns it off then arm64-pmc will crash.

Independently of these counters, libcpucycles uses various OS mechanisms to obtain an estimate of the CPU frequency. This estimate is also available to the caller as cpucycles_persecond().

The methods that libcpucycles uses to ask the OS for an estimated CPU frequency fail on some OS-CPU combinations, in which case libcpucycles falls back to a cpucyclespersecond environment variable, or, if that variable does not exist, an estimate of 2399987654 cycles per second. (This estimate is in a realistic range of CPU speeds, and is close to multiples of 24MHz, 25MHz, and 19.2MHz, which are common crystal frequencies.) The sysadmin can create /etc/cpucyclespersecond to override all of the OS mechanisms.

For counters that do not ask for scaling, the estimated CPU frequency is shown in cpucycles-info as a double-check on the counter results. For counters that ask for scaling, libcpucycles uses the estimated CPU frequency to compute the scaling, so this is not a double-check. If a counter asks for scaling and the estimated CPU frequency does not seem close to a multiple of the counter frequency (possibly with a small power-of-2 denominator) then libcpucycles will throw the counter away, except in the case of fixed-resolution OS counters such as gettimeofday and CLOCK_MONOTONIC.

libcpucycles computes a precision estimate for each counter (times any applicable scaling) as follows. Call the counter 1000 times. Check that the counter has never decreased, and has increased at least once. (A counter where the decrease/increase checks fail is retried 10 times, so 10000 calls overall, and removed if it fails all 10 times.) The precision estimate is then the smallest nonzero difference between adjacent counter results, plus a penalty explained below.

Finally, libcpucycles selects the counter where the precision estimate is the smallest number of cycles. Note that an inaccurate estimate of CPU frequency can influence the choice between a scaled counter and an unscaled counter.

The penalty is as follows:

  • 0 for counters clearly documented as hardware CPU cycle counters (RDPMC, PMCCNTR, RDCYCLE, RDTICK, default-perfevent).

  • 300 for cycle counters that need to be extended from 32 bits.

  • 1000 for other counters (such as various off-core clocks).

  • An extra 10 for each working counter earlier in the libcpucycles list of counters.

For example, a hardware CPU cycle counter that is early in the list and that does not need to be extended from 32 bits will be selected even if it actually has, e.g., a resolution of 8 cycles and 50 cycles of overhead. As another example, tsc and tscasm are generally within 1 or 2 cycles in the smallest nonzero difference between adjacent counter results, so tsc will be be selected ahead of tscasm because it is earlier in the list.

libcpucycles does not carry out its counter selection (typically tens of milliseconds, sometimes even more) as a static initializer; callers are presumed to not want to incur the cost of initialization unless and until they are actually using cpucycles(). A multithreaded caller thus has to place locks around any possibly-first call to cpucycles(), or create its own static initializer (an __attribute__((constructor)) function) with an initial cpucycles() call so that all subsequent cpucycles() calls are thread-safe.


Version: This is version 2026.06.25 of the "Selection" web page.
libcpucycles-20260901/doc/install.md0000644000000000000000000000457415245636444015722 0ustar rootrootPrerequisites: * `python3` (for: build) * `gcc` and/or `clang` (for: build) Currently tested only under Linux, but porting to other systems shouldn't be difficult. ### For sysadmins To install in `/usr/local/{include,lib,bin,man}`: ./configure && make -j8 install ### For developers with an unprivileged account Typically you'll already have export LD_LIBRARY_PATH="$HOME/lib" export LIBRARY_PATH="$HOME/lib" export CPATH="$HOME/include" export MANPATH="$HOME/man" export PATH="$HOME/bin:$PATH" in `$HOME/.profile`. To install in `$HOME/{include,lib,bin,man}`: ./configure --prefix=$HOME && make -j8 install ### For distributors creating a package Run ./configure --prefix=/usr && make -j8 and then follow your usual packaging procedures for the `build/0/package` files: build/0/package/man/man3/cpucycles.3 build/0/package/include/cpucycles.h build/0/package/lib/libcpucycles* build/0/package/bin/cpucycles-info build/0/package/bin/cpucycles-open There are some old systems where libcpucycles requires `-lrt` for `clock_gettime`; currently `libcpucycles.so` doesn't link to `-lrt`, so it's up to the caller to link to `-lrt`. You may wish to provide a package that runs `cpucycles-open` on each boot, but this should be separate from the main `cpucycles` package: `cpucycles` is functional without `cpucycles-open`, and some security policies are contrary to `cpucycles-open`. ### More options You can run ./configure --host=amd64 to override `./configure`'s guess of the architecture that it should compile for. The architecture controls which cycle counters to try compiling: e.g., `amd64` tries compiling `cpucycles/amd64*` and `cpucycles/default*`. Inside the `build` directory, `0` is symlinked to `amd64` for `--host=amd64`. Running `make clean` removes `build/amd64`. Re-running `./configure` automatically starts with `make clean`. A subsequent `./configure --host=arm64` will create `build/arm64` and symlink `0 -> arm64`, without touching an existing `build/amd64`. However, cross-compilers aren't yet selected automatically. Compilers tried are listed in `compilers/default`. Each compiler includes `-fPIC` to create a shared library, `-fvisibility=hidden` to hide non-public symbols in the library, and `-fwrapv` to switch to a slightly less dangerous version of C. The first compiler that seems to work is used to compile everything. libcpucycles-20260901/doc/license.md0000644000000000000000000000053215245636444015664 0ustar rootrootlibcpucycles is hereby placed into the public domain. [SPDX-License-Identifier](https://spdx.dev/ids/): [LicenseRef-PD-hp](https://cr.yp.to/spdx.html) OR [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) OR [0BSD](https://spdx.org/licenses/0BSD.html) OR [MIT-0](https://spdx.org/licenses/MIT-0.html) OR [MIT](https://spdx.org/licenses/MIT.html) libcpucycles-20260901/doc/man/0000755000000000000000000000000015245636444014473 5ustar rootrootlibcpucycles-20260901/doc/man/cpucycles-info.10000644000000000000000000000170115245636444017477 0ustar rootroot.\" Automatically generated by Pandoc 3.1.11.1 .\" .TH "cpucycles\-info" "1" "" "" "" .SS NAME cpucycles\-info \- report information about CPU cycle counters .SS SYNOPSIS .IP .EX cpucycles\-info .EE .SS DESCRIPTION \f[CR]cpucycles\-info\f[R] prints human\-readable information about the cycle counters considered by \f[CR]cpucycles()\f[R]. .PP The format is subject to change but currently includes a \f[CR]cpucycles version\f[R] line, \f[CR]cpucycles tracesetup\f[R] lines showing which cycle counters are considered and how precise they seem to be (with smaller \f[CR]precision\f[R] values being better, except that \f[CR]precision 0\f[R] means a cycle counter that does not seem to work), a \f[CR]cpucycles persecond\f[R] line about the selected cycle counter, a \f[CR]cpucycles implementation\f[R] line about the selected cycle counter, and \f[CR]cpucycles observed persecond\f[R] lines about the selected cycle counter. .SS SEE ALSO \f[B]cpucycles\f[R](3) libcpucycles-20260901/doc/man/cpucycles-open.10000644000000000000000000000121315245636444017503 0ustar rootroot.\" Automatically generated by Pandoc 3.1.11.1 .\" .TH "cpucycles\-open" "1" "" "" "" .SS NAME cpucycles\-open \- open up cycle counting .SS SYNOPSIS .IP .EX cpucycles\-open .EE .SS DESCRIPTION \f[CR]cpucycles\-open\f[R] tries to change some aspects of OS configuration to open up higher\-quality cycle counters for \f[CR]cpucycles\f[R]. .PP Some system administrators may wish to configure \f[CR]cpucycles\-open\f[R] to be run on each boot. However, what \f[CR]cpucycles\f[R] does is contrary to some security policies. .PP \f[CR]cpucycles\-open\f[R] often improves cycle counting, but does not guarantee success. .SS SEE ALSO \f[B]cpucycles\f[R](3) libcpucycles-20260901/doc/man/cpucycles.30000644000000000000000000000363315245636444016556 0ustar rootroot.\" Automatically generated by Pandoc 3.1.11.1 .\" .TH "cpucycles" "3" "" "" "" .SS NAME cpucycles \- count CPU cycles .SS SYNOPSIS .IP .EX #include long long count = cpucycles(); long long persecond = cpucycles_persecond(); const char *implementation = cpucycles_implementation(); const char *version = cpucycles_version(); .EE .PP Link with \f[CR]\-lcpucycles\f[R]. Old systems may also need \f[CR]\-lrt\f[R]. .SS DESCRIPTION \f[CR]cpucycles()\f[R] returns an estimate for the number of CPU cycles that have occurred since an unspecified time in the past (perhaps system boot, perhaps program startup). .PP Accessing true cycle counters can be difficult on some CPUs and operating systems. \f[CR]cpucycles()\f[R] does its best to produce accurate results, but selects a low\-precision counter if the only other option is failure. .PP \f[CR]cpucycles_persecond()\f[R] returns an estimate for the number of CPU cycles per second. This estimate comes from \f[CR]/etc/cpucyclespersecond\f[R] if that file exists, otherwise from various OS mechanisms, otherwise from the \f[CR]cpucyclespersecond\f[R] environment variable if that is set, otherwise 2399987654. .PP \f[CR]cpucycles_implementation()\f[R] returns the name of the counter in use: e.g., \f[CR]\[dq]amd64\-perfpmc\[dq]\f[R]. .PP \f[CR]cpucycles_version()\f[R] returns the \f[CR]libcpucycles\f[R] version number as a string: e.g., \f[CR]\[dq]20260901\[dq]\f[R]. Results of \f[CR]cpucycles_implementation()\f[R] should be interpreted relative to \f[CR]cpucycles_version()\f[R]. .PP \f[CR]cpucycles\f[R] is actually a function pointer. The first call to \f[CR]cpucycles()\f[R] or \f[CR]cpucycles_persecond()\f[R] or \f[CR]cpucycles_implementation()\f[R] selects one of the available counters and updates the \f[CR]cpucycles\f[R] pointer accordingly. Subsequent calls to \f[CR]cpucycles()\f[R] are thread\-safe. .SS SEE ALSO \f[B]gettimeofday\f[R](2), \f[B]clock_gettime\f[R](2) libcpucycles-20260901/doc/readme.md0000644000000000000000000000410115245636444015473 0ustar rootrootlibcpucycles is a microlibrary for counting CPU cycles. Cycle counts are not as detailed as [Falk diagrams](https://gamozolabs.github.io/metrology/2019/08/19/sushi_roll.html) but are the most precise timers available to typical software; they are central tools used in understanding and improving software performance. The libcpucycles [API](api.html) is simple: include ``, call `cpucycles()` to receive a `long long` whenever desired, and link with `-lcpucycles`. [Internally](counters.html), libcpucycles understands machine-level cycle counters for amd64 (both PMC and TSC), arm32, arm64 (both PMC and VCT), loong64, mips64, ppc32, ppc64, riscv32, riscv64, s390x, sparc64, and x86. libcpucycles also understands four OS-level mechanisms, which give varying levels of accuracy: `mach_absolute_time`, `perf_event`, `CLOCK_MONOTONIC`, and, as a fallback, microsecond-resolution `gettimeofday`. When the program first calls `cpucycles()`, libcpucycles automatically benchmarks the available mechanisms and [selects](selection.html) the mechanism that does the best job. Subsequent `cpucycles()` calls are thread-safe and very fast. An accompanying `cpucycles-info` program prints a summary of cycle-counter accuracy. For comparison, there is a simple-sounding `__rdtsc()` API provided by compilers, but this works only on Intel/AMD CPUs and is generally noisier than PMC. There is a `__builtin_readcyclecounter()` that works on more CPUs, but this works only with `clang` and has the same noise problems. Both of these mechanisms put the burden on the caller to figure out what can be done on other CPUs. Various packages include their own more portable abstraction layers for counting cycles (see, e.g., FFTW's [`cycle.h`](https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h), used to automatically select from among multiple implementations provided by FFTW), but this creates per-package effort to keep up with the latest cycle counters. The goal of libcpucycles is to provide state-of-the-art cycle counting centrally for all packages to use. Latest release: [20260901](download.html). libcpucycles-20260901/doc/security.md0000644000000000000000000001170115245636444016111 0ustar rootroot### Timing attacks Many security systems have been shown to be breakable by "timing attacks". These attacks extract secrets by analyzing timings of the legitimate user's operations on secret data. See the June 2022 survey page [https://timing.attacks.cr.yp.to](https://timing.attacks.cr.yp.to) for an overview and further references. Sometimes these attacks are used as motivation to disable the attacker's access to various timing mechanisms. For example, Firefox rounds its `performance.now` timer to 1-millisecond resolution ["to mitigate potential security threats"](https://web.archive.org/web/20220428142858/https://developer.mozilla.org/en-US/docs/web/api/performance/now). As another example, reducing `/proc/sys/kernel/perf_event_paranoid` under Linux to 2 (from 3 or higher), so that libcpucycles has access to the best available Intel/AMD cycle counter (RDPMC), also means making this cycle counter and other performance-monitoring counters available to any attacker-controlled software running on the computer. Perhaps this helps timing attacks, not to mention the possibility of opening up other vulnerabilities via the complicated `perf_event` interface. As yet another example, ARM CPUs disable user access to the main CPU cycle counter by default. Allowing user access to the cycle counter (via a kernel module or other kernel configuration) could help attacks. Given the availability of simple mechanisms to disable RDPMC etc., it is easy to recommend using those mechanisms. To avoid creating unnecessary tension between those recommendations and the use of libcpucycles, applications that use libcpucycles should be structured so that high-resolution timers are used only on controlled development and benchmarking machines, not on general end-user machines. This structure might seem incompatible with using cycle counts to automatically select the best of multiple options, as in FFTW. However, infrastructure introduced in [lib25519](https://lib25519.cr.yp.to) automatically selects options on end-user machines based on cycle counts that were _collected on benchmarking machines_. The above text should not be understood as endorsing the idea that disabling timers is an _effective_ defense against timing attacks. Certainly disabling high-resolution timers is not sufficient for security: there are many ways for attackers to amplify timing signals and to statistically filter out noise from low-resolution timers. Disabling _every_ standard timing mechanism on the machine does not stop the attacker from accessing a remote timer or a counter maintained by the attacker's software. Perhaps disabling timers sometimes makes the difference between a feasible attack and an infeasible attack, but evaluating this is extremely difficult. Meanwhile there is an auditable methodology available to stop timing attacks: constant-time programming, which systematically cuts off data flow from secrets to timings. For example, constant-time programming does not permit comparisons involving secrets (e.g., `x>y` where `x` or `y` is secret): comparisons are sometimes compiled into branches, and branches take variable time. The [cryptoint](https://cr.yp.to/papers.html#cryptoint) library provides constant-time comparison operations. As another example, constant-time programming disables overclocking mechanisms such as Turbo Boost: secrets affect a CPU's power consumption, and overclocking creates data flow from power consumption to timings. The importance of disabling overclocking is illustrated by the [Hertzbleed attack](https://www.hertzbleed.com) extracting secret keys from the SIKE cryptosystem (before SIKE was broken in other ways), and by an [independent attack](https://arxiv.org/abs/2206.07012) extracting secret AES keys. This is why [https://timing.attacks.cr.yp.to](https://timing.attacks.cr.yp.to) recommends turning off Turbo Boost "right now", and explains the mechanisms available to do this. One non-security reason that it was already normal (although not universal) for manufacturers to provide these mechanisms to end users is that Turbo Boost has a reputation for causing premature hardware failures. Turbo Boost also provides very little speed benefit for modern multithreaded vectorized applications. Another reaction to timing attacks is to apply "masking" techniques. These techniques _seem_ to make it more difficult for attackers to extract secrets from power consumption and other side channels. However, as [https://timing.attacks.cr.yp.to](https://timing.attacks.cr.yp.to) explains, it is "practically impossible for an auditor to obtain any real assurance that these techniques are secure". See the paper ["Breaking a fifth-order masked implementation of CRYSTALS-Kyber by copy-paste"](https://eprint.iacr.org/2022/1713) for an example of a security failure in a masked implementation. ### Setuid programs libcpucycles is not intended for usage in setuid programs. It often calls further programs to estimate the CPU frequency, and it inspects possibly untrustworthy environment variables. libcpucycles-20260901/doc/selection.md0000644000000000000000000001502115245636444016226 0ustar rootrootHere is how libcpucycles decides which cycle counter to use. The underlying principles are as follows: * Failure is not allowed. Using a low-resolution timer such as `gettimeofday()` to estimate cycle counts is not desirable but is better than providing no information. * A counter that does well on some CPUs and OSes can do badly on others. The counter selection in libcpucycles is based not just on rules set at compile time but also on measurements of how well the counters perform when the program first calls `cpucycles()`. * A critical application of cycle counting is collecting cycle counts for multiple options to see which option is faster. It is the caller's responsibility, given cycle counts for many runs of whichever function is being benchmarked, to compute robust statistics such as [stabilized quartiles](https://cr.yp.to/papers.html#rsrst), so as to filter out occasional cycle-count jumps caused by migration to another core (if the benchmark is not pinned to a single core) or by interrupts from other OS activity, not to mention intrinsic variations in the function's run time. libcpucycles does not reject an otherwise attractive counter merely because of occasional jumps. * Cycle-counting overhead is not desirable, but does not directly affect comparisons of multiple options measured using the same cycle counter, so it is less important than consistent major errors such as treating 2^32^ + x cycles as x cycles. (Performance experts seeing a function that takes billions of cycles usually focus on smaller subroutines, but libcpucycles should not break larger measurements.) This is why libcpucycles does not provide direct access to 32-bit cycle counters: it provides wrappers that combine the counters with gettimeofday() to produce 64 bits, even though this incurs some extra overhead. * The noise introduced by typical off-core clocks, such as multiplying a 24MHz clock by 86 to estimate cycles on a 2.064GHz CPU core, comes in small part from low resolution but much more from changes in CPU frequency: e.g., a 10000-cycle computation might be measured as 20000 cycles when the CPU enters a power-saving mode. When libcpucycles has access to what is believed to be an on-core cycle counter, it uses that even when its measurements show some noise. (Choosing an on-core cycle counter does not magically eliminate the change in the relative speed of the CPU and DRAM; the usual advice to warm up the CPU and set constant frequencies if possible still applies.) When `cpucycles()` is first called, libcpucycles tries running each cycle counter that has been compiled into the library. For example, for 64-bit ARM CPUs, libcpucycles will try `arm64-pmc`, `arm64-vct`, `default-gettimeofday`, `default-mach`, `default-monotonic`, and `default-perfevent`, minus any of those that failed to compile. Cycle counters that fail at run time with SIGILL (or SIGFPE or SIGBUS or SIGSEGV or SIGABRT) are eliminated from the list. For example, `arm64-pmc` will fail with SIGILL if the kernel does not allow user access to `PMCCNTR_EL0`. Beware that libcpucycles does not catch SIGILL after its initial tests: if the kernel initially allows user access to `PMCCNTR_EL0` but later turns it off then `arm64-pmc` will crash. Independently of these counters, libcpucycles uses various OS mechanisms to obtain an _estimate_ of the CPU frequency. This estimate is also available to the caller as `cpucycles_persecond()`. The methods that libcpucycles uses to ask the OS for an estimated CPU frequency fail on some OS-CPU combinations, in which case libcpucycles falls back to a `cpucyclespersecond` environment variable, or, if that variable does not exist, an estimate of 2399987654 cycles per second. (This estimate is in a realistic range of CPU speeds, and is close to multiples of 24MHz, 25MHz, and 19.2MHz, which are common crystal frequencies.) The sysadmin can create `/etc/cpucyclespersecond` to override all of the OS mechanisms. For counters that do not ask for scaling, the estimated CPU frequency is shown in `cpucycles-info` as a double-check on the counter results. For counters that ask for scaling, libcpucycles uses the estimated CPU frequency to compute the scaling, so this is not a double-check. If a counter asks for scaling and the estimated CPU frequency does not seem close to a multiple of the counter frequency (possibly with a small power-of-2 denominator) then libcpucycles will throw the counter away, except in the case of fixed-resolution OS counters such as `gettimeofday` and `CLOCK_MONOTONIC`. libcpucycles computes a precision estimate for each counter (times any applicable scaling) as follows. Call the counter 1000 times. Check that the counter has never decreased, and has increased at least once. (A counter where the decrease/increase checks fail is retried 10 times, so 10000 calls overall, and removed if it fails all 10 times.) The precision estimate is then the smallest nonzero difference between adjacent counter results, plus a penalty explained below. Finally, libcpucycles selects the counter where the precision estimate is the smallest number of cycles. Note that an inaccurate estimate of CPU frequency can influence the choice between a scaled counter and an unscaled counter. The penalty is as follows: * 0 for counters clearly documented as hardware CPU cycle counters (RDPMC, PMCCNTR, RDCYCLE, RDTICK, `default-perfevent`). * 300 for cycle counters that need to be extended from 32 bits. * 1000 for other counters (such as various off-core clocks). * An extra 10 for each working counter earlier in the libcpucycles list of counters. For example, a hardware CPU cycle counter that is early in the list and that does not need to be extended from 32 bits will be selected even if it actually has, e.g., a resolution of 8 cycles and 50 cycles of overhead. As another example, `tsc` and `tscasm` are generally within 1 or 2 cycles in the smallest nonzero difference between adjacent counter results, so `tsc` will be be selected ahead of `tscasm` because it is earlier in the list. libcpucycles does _not_ carry out its counter selection (typically tens of milliseconds, sometimes even more) as a static initializer; callers are presumed to not want to incur the cost of initialization unless and until they are actually using `cpucycles()`. A multithreaded caller thus has to place locks around any possibly-first call to `cpucycles()`, or create its own static initializer (an `__attribute__((constructor))` function) with an initial `cpucycles()` call so that all subsequent `cpucycles()` calls are thread-safe. libcpucycles-20260901/scripts-build/0000755000000000000000000000000015245636444015737 5ustar rootrootlibcpucycles-20260901/scripts-build/install0000755000000000000000000000142515245636444017335 0ustar rootroot#!/usr/bin/env python3 import os import sys import shutil import tempfile destdir = os.getenv('DESTDIR','') prefix = sys.argv[1] dirs = 'man/man1','man/man3','lib','include','bin' install = {} os.umask(0o22) for target in dirs: install[target] = f'{destdir}{prefix}/{target}' os.makedirs(install[target],exist_ok=True) os.umask(0o77) for target in dirs: with tempfile.TemporaryDirectory(dir=install[target]) as t: for fn in sorted(os.listdir('package/'+target)): try: shutil.copy2('package/%s/%s' % (target,fn),'%s/%s' % (t,fn),follow_symlinks=False) except TypeError: # XXX: old python3; should copy symlinks manually shutil.copy2('package/%s/%s' % (target,fn),'%s/%s' % (t,fn)) os.rename('%s/%s' % (t,fn),'%s/%s' % (install[target],fn)) libcpucycles-20260901/scripts-build/staticlib0000755000000000000000000000023615245636444017644 0ustar rootroot#!/bin/sh rm -f package/lib/libcpucycles.a ar cr package/lib/libcpucycles.a "$@" ranlib package/lib/libcpucycles.a || : chmod 644 package/lib/libcpucycles.a libcpucycles-20260901/version0000644000000000000000000000001115245636444014553 0ustar rootroot20260901