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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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