1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/tools/llvm-exegesis/lib/PerfHelper.h
Vy Nguyen 0724050861 Reland [llvm-exegesis] Add benchmark latency option on X86 that uses LBR for more precise measurements.
Starting with Skylake, the LBR contains the precise number of cycles between the two
        consecutive branches.
        Making use of this will hopefully make the measurements more precise than the
        existing methods of using RDTSC.

                Differential Revision: https://reviews.llvm.org/D77422

New change: check for existence of field `cycles` in perf_branch_entry before enabling this mode.
This should prevent compilation errors when building for older kernel whose headers don't support it.
2020-07-27 12:38:05 -04:00

113 lines
3.1 KiB
C++

//===-- PerfHelper.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Helpers for measuring perf events.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H
#define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <functional>
#include <memory>
struct perf_event_attr;
namespace llvm {
namespace exegesis {
namespace pfm {
// Returns true on error.
bool pfmInitialize();
void pfmTerminate();
// Retrieves the encoding for the event described by pfm_event_string.
// NOTE: pfm_initialize() must be called before creating PerfEvent objects.
class PerfEvent {
public:
// http://perfmon2.sourceforge.net/manv4/libpfm.html
// Events are expressed as strings. e.g. "INSTRUCTION_RETIRED"
explicit PerfEvent(StringRef PfmEventString);
PerfEvent(const PerfEvent &) = delete;
PerfEvent(PerfEvent &&other);
~PerfEvent();
// The pfm_event_string passed at construction time.
StringRef name() const;
// Whether the event was successfully created.
bool valid() const;
// The encoded event to be passed to the Kernel.
const perf_event_attr *attribute() const;
// The fully qualified name for the event.
// e.g. "snb_ep::INSTRUCTION_RETIRED:e=0:i=0:c=0:t=0:u=1:k=0:mg=0:mh=1"
StringRef getPfmEventString() const;
protected:
PerfEvent() = default;
std::string EventString;
std::string FullQualifiedEventString;
perf_event_attr *Attr;
};
// Uses a valid PerfEvent to configure the Kernel so we can measure the
// underlying event.
class Counter {
public:
// event: the PerfEvent to measure.
explicit Counter(PerfEvent &&event);
Counter(const Counter &) = delete;
Counter(Counter &&other) = default;
virtual ~Counter();
/// Starts the measurement of the event.
virtual void start();
/// Stops the measurement of the event.
void stop();
/// Returns the current value of the counter or -1 if it cannot be read.
int64_t read() const;
/// Returns the current value of the counter or error if it cannot be read.
/// FunctionBytes: The benchmark function being executed.
/// This is used to filter out the measurements to ensure they are only
/// within the benchmarked code.
/// If empty (or not specified), then no filtering will be done.
/// Not all counters choose to use this.
virtual llvm::Expected<llvm::SmallVector<int64_t, 4>>
readOrError(StringRef FunctionBytes = StringRef()) const;
virtual int numValues() const;
protected:
PerfEvent Event;
#ifdef HAVE_LIBPFM
int FileDescriptor = -1;
#endif
};
} // namespace pfm
} // namespace exegesis
} // namespace llvm
#endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H