├── .gitignore ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── circle.yml ├── setup.py ├── src ├── rdtsc.c └── rdtsc │ └── __init__.py ├── test_requirements.txt ├── tests ├── __init__.py └── test_basic.py └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | sdist/ 4 | env/ 5 | *.egg-info/ 6 | *.egg_info/ 7 | 8 | *.pyc 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | .cache/ 14 | .coverage 15 | .tox 16 | *.xml 17 | htmlcov 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2015-2016, James Brown 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12 | SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 | OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 | CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include src/*.c 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a crappy ctypes-based wrapper around the X86 RDTSC instruction to get cycle timers. 2 | 3 | It will only work on x86-64 systems and probably requires GCC to install. Caveat emptor. 4 | 5 | [![CircleCI](https://circleci.com/gh/Roguelazer/rdtsc.svg?style=svg)](https://circleci.com/gh/Roguelazer/rdtsc) 6 | 7 | Usage 8 | ===== 9 | 10 | ```python 11 | import rdtsc 12 | 13 | start = rdtsc.get_cycles() 14 | # do stuff 15 | end = rdtsc.get_cycles() 16 | ``` 17 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | python: 3 | version: 3.5.0 4 | dependencies: 5 | override: 6 | - pip install tox tox-pyenv 7 | - pyenv local 2.7.11 3.4.4 3.5.1 8 | test: 9 | override: 10 | - tox 11 | post: 12 | - cp coverage.xml $CIRCLE_ARTIFACTS/ 13 | - cp -R htmlcov $CIRCLE_ARTIFACTS/ 14 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | import subprocess 6 | 7 | from setuptools import setup 8 | 9 | from distutils.command.build import build 10 | 11 | if sys.platform == 'darwin': 12 | sofile = 'rdtsc.dylib' 13 | elif sys.platform == 'win32': 14 | sofile = 'rdtsc.dll' 15 | else: 16 | sofile = 'rdtsc.so.1' 17 | 18 | 19 | class RTDSCBuild(build): 20 | def initialize_options(self): 21 | build.initialize_options(self) 22 | self.build_base = os.path.join(self.build_base, 'python') 23 | 24 | def run(self): 25 | subprocess.call(['cc', '-shared', '-o', 26 | os.path.join('src', 'rdtsc', sofile), '-fPIC', 27 | 'src/rdtsc.c']) 28 | build.run(self) 29 | 30 | 31 | setup( 32 | name="rdtsc", 33 | version="0.2.1", 34 | author="James Brown", 35 | author_email="Roguelazer@gmail.com", 36 | url="https://github.com/Roguelazer/rdtsc", 37 | license="ISC", 38 | packages=['rdtsc'], 39 | package_dir={'rdtsc': 'src/rdtsc'}, 40 | cmdclass={'build': RTDSCBuild}, 41 | package_data={'rdtsc': [sofile]}, 42 | keywords=["performance"], 43 | description="Cycle timer wrapping the Intel x86 RTDSC instruction", 44 | classifiers=[ 45 | "Development Status :: 3 - Alpha", 46 | "Programming Language :: C", 47 | "Programming Language :: Python :: 2.7", 48 | "Programming Language :: Python :: 3.4", 49 | "Programming Language :: Python :: 3.5", 50 | "Intended Audience :: Developers", 51 | "License :: OSI Approved :: ISC License (ISCL)", 52 | ], 53 | zip_safe=False, 54 | ) 55 | -------------------------------------------------------------------------------- /src/rdtsc.c: -------------------------------------------------------------------------------- 1 | extern unsigned long long get_cycles() 2 | { 3 | long long out; 4 | asm volatile( 5 | "RDTSCP;" /* outputs to EDX:EAX and the (unused) cpuid to ECX*/ 6 | "SHLQ $32,%%rdx;" 7 | "ORQ %%rdx,%%rax;" 8 | "MOVQ %%rax,%0;" 9 | :"=r"(out) 10 | : /*no input*/ 11 | :"rdx","rax", "rcx" 12 | ); 13 | return out; 14 | } 15 | -------------------------------------------------------------------------------- /src/rdtsc/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import ctypes 3 | 4 | import pkg_resources 5 | 6 | 7 | version_info = (0, 2, 1) 8 | __version__ = '.'.join(str(s) for s in version_info) 9 | __author__ = 'James Brown ' 10 | __license__ = 'ISC' 11 | 12 | 13 | if sys.platform == 'darwin': 14 | sofile = 'rdtsc.dylib' 15 | elif sys.platform == 'win32': 16 | sofile = 'rdtsc.dll' 17 | else: 18 | sofile = 'rdtsc.so.1' 19 | 20 | path = pkg_resources.resource_filename('rdtsc', sofile) 21 | so = ctypes.CDLL(path, use_errno=True) 22 | 23 | get_cycles = so.get_cycles 24 | get_cycles.argtypes = [] 25 | get_cycles.restype = ctypes.c_ulonglong 26 | -------------------------------------------------------------------------------- /test_requirements.txt: -------------------------------------------------------------------------------- 1 | pytest==2.9.2 2 | pytest-cov==2.2.1 3 | six 4 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roguelazer/rdtsc/a4ea280e02781e3a65e8905535bb8df768e097f1/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_basic.py: -------------------------------------------------------------------------------- 1 | import six 2 | 3 | import rdtsc 4 | 5 | 6 | def test_basic(): 7 | start = rdtsc.get_cycles() 8 | end = rdtsc.get_cycles() 9 | assert isinstance(end, six.integer_types) 10 | assert isinstance(start, six.integer_types) 11 | assert end > start 12 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | basepython = python3.5 3 | envlist = py27,py34, py35 4 | 5 | [testenv] 6 | usedevelop = False 7 | basepython = python3.5 8 | install_command = pip install --upgrade {opts} {packages} 9 | deps = 10 | -rtest_requirements.txt 11 | commands = 12 | py.test --cov=rdtsc --cov-report=term-missing --cov-report=html --cov-report=xml --junit-prefix={envname}: --junit-xml={env:CIRCLE_TEST_REPORTS:.}/test-{envname}.xml -v tests/ 13 | 14 | [testenv:py27] 15 | basepython = python2.7 16 | 17 | [testenv:py34] 18 | basepython = python3.4 19 | 20 | [testenv:py35] 21 | basepython = python3.5 22 | 23 | [flake8] 24 | max-line-length=120 25 | --------------------------------------------------------------------------------