Skip to content

Commit

Permalink
Add cycle count getter for more platforms.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Jan 21, 2020
1 parent 0549bf1 commit 967ffc9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
1 change: 1 addition & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Julia includes code from the following projects, which have their own licenses:
- [MINGW](https://sourceforge.net/p/mingw/mingw-org-wsl/ci/legacy/tree/mingwrt/mingwex/dirname.c) (for dirname implementation on Windows) [MIT]
- [NetBSD](https://www.netbsd.org/about/redistribution.html) (for setjmp, longjmp, and strptime implementations on Windows) [BSD-3]
- [Python](https://docs.python.org/2/license.html) (for strtod and joinpath implementation on Windows) [BSD-3, effectively]
- [Google Benchmark](https://github.com/google/benchmark) (for cyclecount implementation) [Apache 2.0]

The following components included in Julia `Base` have their own separate licenses:

Expand Down
4 changes: 2 additions & 2 deletions src/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ jl_timing_block_t *jl_pop_timing_block(jl_timing_block_t *cur_block)

void jl_timing_block_start(jl_timing_block_t *cur_block)
{
_jl_timing_block_start(cur_block, rdtscp());
_jl_timing_block_start(cur_block, cycleclock());
}

void jl_timing_block_stop(jl_timing_block_t *cur_block)
{
_jl_timing_block_stop(cur_block, rdtscp());
_jl_timing_block_stop(cur_block, cycleclock());
}

#else
Expand Down
30 changes: 24 additions & 6 deletions src/timing.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,29 @@ void jl_timing_block_stop(jl_timing_block_t *cur_block);
#define JL_TIMING(owner)
#else

static inline uint64_t rdtscp(void)
// number of cycles since power-on
static inline uint64_t cycleclock(void)
{
uint64_t rax,rdx;
asm volatile ( "rdtscp\n" : "=a" (rax), "=d" (rdx) : : "rcx" );
return (rdx << 32) + rax;
#if defined(_CPU_X86_64_)
uint64_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return (high << 32) | low;
#elif defined(_CPU_X86_)
int64_t ret;
__asm__ volatile("rdtsc" : "=A"(ret));
return ret;
#elif defined(_CPU_AARCH64_)
// System timer of ARMv8 runs at a different frequency than the CPU's.
// The frequency is fixed, typically in the range 1-50MHz. It can be
// read at CNTFRQ special register. We assume the OS has set up
// the virtual timer properly.
int64_t virtual_timer_value;
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
return virtual_timer_value;
#else
#error No cycleclock() definition for your platform
// copy from https://github.com/google/benchmark/blob/v1.5.0/src/cycleclock.h
#endif
}

#define JL_TIMING_OWNERS \
Expand Down Expand Up @@ -107,7 +125,7 @@ STATIC_INLINE void _jl_timing_block_start(jl_timing_block_t *block, uint64_t t)
}

STATIC_INLINE uint64_t _jl_timing_block_init(jl_timing_block_t *block, int owner) {
uint64_t t = rdtscp();
uint64_t t = cycleclock();
block->owner = owner;
block->total = 0;
#ifdef JL_DEBUG_BUILD
Expand All @@ -127,7 +145,7 @@ STATIC_INLINE void _jl_timing_block_ctor(jl_timing_block_t *block, int owner) {
}

STATIC_INLINE void _jl_timing_block_destroy(jl_timing_block_t *block) {
uint64_t t = rdtscp();
uint64_t t = cycleclock();
_jl_timing_block_stop(block, t);
jl_timing_data[block->owner] += block->total;
jl_timing_block_t **pcur = jl_current_task ? &jl_current_task->timing_stack : &jl_root_timing;
Expand Down

0 comments on commit 967ffc9

Please sign in to comment.