Skip to content

get cpu frequency #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ Usage
=====

```python
import time
import rdtsc

start = rdtsc.get_cycles()
# do stuff
time.sleep(5)
end = rdtsc.get_cycles()
frequency = rdtsc.get_cpu_frequency()

print((end - start)/(frequency * 10 ** 6))
```
60 changes: 52 additions & 8 deletions src/rdtsc.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,58 @@
#include <unistd.h>
#include <sys/time.h>

extern unsigned long long get_cycles()
{
long long out;
asm volatile(
"RDTSCP;" /* outputs to EDX:EAX and the (unused) cpuid to ECX*/
"SHLQ $32,%%rdx;"
"ORQ %%rdx,%%rax;"
"MOVQ %%rax,%0;"
:"=r"(out)
: /*no input*/
:"rdx","rax", "rcx"
);
"RDTSCP;" /* outputs to EDX:EAX and the (unused) cpuid to ECX*/
"SHLQ $32,%%rdx;"
"ORQ %%rdx,%%rax;"
"MOVQ %%rax,%0;"
:"=r"(out)
: /*no input*/
:"rdx","rax", "rcx"
);
return out;
}

/**
* Get time delta in microseconds.
*/
static long get_us_interval(struct timeval *start, struct timeval *end) {
return (((end->tv_sec - start->tv_sec) * 1000000)
+ (end->tv_usec - start->tv_usec));
}

/**
* This is a microbenchmark to get cpu frequency the process is running on. The
* returned value is used to convert TSC counter values to microseconds.
*
* @return double.
* @author cjiang
*
* see https://github.com/FriendsOfPHP/uprofiler
*/
extern double get_cpu_frequency() {
struct timeval start;
struct timeval end;
long long tsc_start;
long long tsc_end;

if (gettimeofday(&start, 0)) {
return 0.0;
}

tsc_start = get_cycles();

/* Sleep for 5 miliseconds. Comparaing with gettimeofday's few microseconds
* execution time, this should be enough. */
usleep(5000);
if (gettimeofday(&end, 0)) {
return 0.0;
}

tsc_end = get_cycles();

return (tsc_end - tsc_start) * 1.0 / (get_us_interval(&start, &end));
}
4 changes: 4 additions & 0 deletions src/rdtsc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@
get_cycles = so.get_cycles
get_cycles.argtypes = []
get_cycles.restype = ctypes.c_ulonglong

get_cpu_frequency = so.get_cpu_frequency
get_cpu_frequency.argtypes = []
get_cpu_frequency.restype = ctypes.c_double