Browse Source
This adds cycle min/max/avg to the statistics. Supported on x86 and x86_64 (natively through rdtsc), as well as Linux (perf syscall).0.14
Wladimir J. van der Laan
8 years ago
5 changed files with 121 additions and 5 deletions
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "perf.h" |
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) |
||||
|
||||
/* These architectures support quering the cycle counter
|
||||
* from user space, no need for any syscall overhead. |
||||
*/ |
||||
void perf_init(void) { } |
||||
void perf_fini(void) { } |
||||
|
||||
#elif defined(__linux__) |
||||
|
||||
#include <unistd.h> |
||||
#include <sys/syscall.h> |
||||
#include <linux/perf_event.h> |
||||
|
||||
static int fd = -1; |
||||
static struct perf_event_attr attr; |
||||
|
||||
void perf_init(void) |
||||
{ |
||||
attr.type = PERF_TYPE_HARDWARE; |
||||
attr.config = PERF_COUNT_HW_CPU_CYCLES; |
||||
fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); |
||||
} |
||||
|
||||
void perf_fini(void) |
||||
{ |
||||
if (fd != -1) { |
||||
close(fd); |
||||
} |
||||
} |
||||
|
||||
uint64_t perf_cpucycles(void) |
||||
{ |
||||
uint64_t result = 0; |
||||
if (fd == -1 || read(fd, &result, sizeof(result)) < (ssize_t)sizeof(result)) { |
||||
return 0; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
#else /* Unhandled platform */ |
||||
|
||||
void perf_init(void) { } |
||||
void perf_fini(void) { } |
||||
uint64_t perf_cpucycles(void) { return 0; } |
||||
|
||||
#endif |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/** Functions for measurement of CPU cycles */ |
||||
#ifndef H_PERF |
||||
#define H_PERF |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#if defined(__i386__) |
||||
|
||||
static inline uint64_t perf_cpucycles(void) |
||||
{ |
||||
uint64_t x; |
||||
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); |
||||
return x; |
||||
} |
||||
|
||||
#elif defined(__x86_64__) |
||||
|
||||
static inline uint64_t perf_cpucycles(void) |
||||
{ |
||||
uint32_t hi, lo; |
||||
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); |
||||
return ((uint64_t)lo)|(((uint64_t)hi)<<32); |
||||
} |
||||
#else |
||||
|
||||
uint64_t perf_cpucycles(void); |
||||
|
||||
#endif |
||||
|
||||
void perf_init(void); |
||||
void perf_fini(void); |
||||
|
||||
#endif // H_PERF
|
Loading…
Reference in new issue