QBenchlib: pass the metric type alongside the measurement value
And pass the value in a qreal, which is what QBenchlib stores anyway. This increases the code size a little because the conversion from integer to qreal is in multiple places, but doesn't meaningfully increase the overhead: in the SysV ABI, we still return Measurement in registers and even using the floating point registers where applicable. This is the first step in allowing the Perf benchmarker to benchmark more than one event. Change-Id: I3c79b7e08fa346988dfefffd172027a8677f17c0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
0f55580ec5
commit
985b942152
@ -96,8 +96,8 @@ int QBenchmarkTestMethodData::adjustIterationCount(int suggestion)
|
|||||||
return iterationCount;
|
return iterationCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBenchmarkTestMethodData::setResult(
|
void QBenchmarkTestMethodData::setResult(QBenchmarkMeasurerBase::Measurement m,
|
||||||
qreal value, QTest::QBenchmarkMetric metric, bool setByMacro)
|
bool setByMacro)
|
||||||
{
|
{
|
||||||
bool accepted = false;
|
bool accepted = false;
|
||||||
|
|
||||||
@ -114,9 +114,9 @@ void QBenchmarkTestMethodData::setResult(
|
|||||||
// Test the result directly without calling the measurer if the minimum time
|
// Test the result directly without calling the measurer if the minimum time
|
||||||
// has been specified on the command line with -minimumvalue.
|
// has been specified on the command line with -minimumvalue.
|
||||||
else if (QBenchmarkGlobalData::current->walltimeMinimum != -1)
|
else if (QBenchmarkGlobalData::current->walltimeMinimum != -1)
|
||||||
accepted = (value > QBenchmarkGlobalData::current->walltimeMinimum);
|
accepted = (m.value > QBenchmarkGlobalData::current->walltimeMinimum);
|
||||||
else
|
else
|
||||||
accepted = QBenchmarkGlobalData::current->measurer->isMeasurementAccepted(value);
|
accepted = QBenchmarkGlobalData::current->measurer->isMeasurementAccepted(m);
|
||||||
|
|
||||||
// Accept the result or double the number of iterations.
|
// Accept the result or double the number of iterations.
|
||||||
if (accepted)
|
if (accepted)
|
||||||
@ -125,7 +125,7 @@ void QBenchmarkTestMethodData::setResult(
|
|||||||
iterationCount *= 2;
|
iterationCount *= 2;
|
||||||
|
|
||||||
this->result = QBenchmarkResult(
|
this->result = QBenchmarkResult(
|
||||||
QBenchmarkGlobalData::current->context, value, iterationCount, metric, setByMacro);
|
QBenchmarkGlobalData::current->context, m.value, iterationCount, m.metric, setByMacro);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -157,8 +157,8 @@ QTest::QBenchmarkIterationController::QBenchmarkIterationController()
|
|||||||
*/
|
*/
|
||||||
QTest::QBenchmarkIterationController::~QBenchmarkIterationController()
|
QTest::QBenchmarkIterationController::~QBenchmarkIterationController()
|
||||||
{
|
{
|
||||||
const qreal result = QTest::endBenchmarkMeasurement();
|
QBenchmarkMeasurerBase::Measurement measurement = QTest::endBenchmarkMeasurement();
|
||||||
QBenchmarkTestMethodData::current->setResult(result, QBenchmarkGlobalData::current->measurer->metricType());
|
QBenchmarkTestMethodData::current->setResult(measurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
@ -209,7 +209,7 @@ void QTest::beginBenchmarkMeasurement()
|
|||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
*/
|
*/
|
||||||
quint64 QTest::endBenchmarkMeasurement()
|
QBenchmarkMeasurerBase::Measurement QTest::endBenchmarkMeasurement()
|
||||||
{
|
{
|
||||||
// the clock is ticking before the line below, don't add code here.
|
// the clock is ticking before the line below, don't add code here.
|
||||||
return QBenchmarkGlobalData::current->measurer->stop();
|
return QBenchmarkGlobalData::current->measurer->stop();
|
||||||
@ -234,7 +234,7 @@ quint64 QTest::endBenchmarkMeasurement()
|
|||||||
*/
|
*/
|
||||||
void QTest::setBenchmarkResult(qreal result, QTest::QBenchmarkMetric metric)
|
void QTest::setBenchmarkResult(qreal result, QTest::QBenchmarkMetric metric)
|
||||||
{
|
{
|
||||||
QBenchmarkTestMethodData::current->setResult(result, metric, false);
|
QBenchmarkTestMethodData::current->setResult({ result, metric }, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -139,7 +139,7 @@ public:
|
|||||||
bool isBenchmark() const { return result.valid; }
|
bool isBenchmark() const { return result.valid; }
|
||||||
bool resultsAccepted() const { return resultAccepted; }
|
bool resultsAccepted() const { return resultAccepted; }
|
||||||
int adjustIterationCount(int suggestion);
|
int adjustIterationCount(int suggestion);
|
||||||
void setResult(qreal value, QTest::QBenchmarkMetric metric, bool setByMacro = true);
|
void setResult(QBenchmarkMeasurerBase::Measurement m, bool setByMacro = true);
|
||||||
|
|
||||||
QBenchmarkResult result;
|
QBenchmarkResult result;
|
||||||
bool resultAccepted = false;
|
bool resultAccepted = false;
|
||||||
@ -155,7 +155,7 @@ namespace QTest
|
|||||||
void setIterationCount(int count);
|
void setIterationCount(int count);
|
||||||
|
|
||||||
void beginBenchmarkMeasurement();
|
void beginBenchmarkMeasurement();
|
||||||
quint64 endBenchmarkMeasurement();
|
QBenchmarkMeasurerBase::Measurement endBenchmarkMeasurement();
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -18,16 +18,16 @@ void QBenchmarkEvent::start()
|
|||||||
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
|
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkEvent::stop()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkEvent::stop()
|
||||||
{
|
{
|
||||||
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
|
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
|
||||||
return eventCounter;
|
return { qreal(eventCounter), QTest::Events };
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's very tempting to simply reject a measurement if 0 events
|
// It's very tempting to simply reject a measurement if 0 events
|
||||||
// where counted, however that is a possible situation and returning
|
// where counted, however that is a possible situation and returning
|
||||||
// false here will create a infinite loop. Do not change this.
|
// false here will create a infinite loop. Do not change this.
|
||||||
bool QBenchmarkEvent::isMeasurementAccepted(qint64 measurement)
|
bool QBenchmarkEvent::isMeasurementAccepted(QBenchmarkMeasurerBase::Measurement measurement)
|
||||||
{
|
{
|
||||||
Q_UNUSED(measurement);
|
Q_UNUSED(measurement);
|
||||||
return true;
|
return true;
|
||||||
@ -44,11 +44,6 @@ int QBenchmarkEvent::adjustMedianCount(int suggestion)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::QBenchmarkMetric QBenchmarkEvent::metricType()
|
|
||||||
{
|
|
||||||
return QTest::Events;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This could be done in a much better way, this is just the beginning.
|
// This could be done in a much better way, this is just the beginning.
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
bool QBenchmarkEvent::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
|
bool QBenchmarkEvent::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
|
||||||
|
@ -28,11 +28,10 @@ public:
|
|||||||
QBenchmarkEvent();
|
QBenchmarkEvent();
|
||||||
~QBenchmarkEvent();
|
~QBenchmarkEvent();
|
||||||
void start() override;
|
void start() override;
|
||||||
qint64 stop() override;
|
Measurement stop() override;
|
||||||
bool isMeasurementAccepted(qint64 measurement) override;
|
bool isMeasurementAccepted(Measurement measurement) override;
|
||||||
int adjustIterationCount(int suggestion) override;
|
int adjustIterationCount(int suggestion) override;
|
||||||
int adjustMedianCount(int suggestion) override;
|
int adjustMedianCount(int suggestion) override;
|
||||||
QTest::QBenchmarkMetric metricType() override;
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
|
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||||
#else
|
#else
|
||||||
|
@ -16,14 +16,14 @@ void QBenchmarkTimeMeasurer::start()
|
|||||||
time.start();
|
time.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkTimeMeasurer::stop()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkTimeMeasurer::stop()
|
||||||
{
|
{
|
||||||
return time.elapsed();
|
return { qreal(time.elapsed()), QTest::WalltimeMilliseconds };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QBenchmarkTimeMeasurer::isMeasurementAccepted(qint64 measurement)
|
bool QBenchmarkTimeMeasurer::isMeasurementAccepted(Measurement measurement)
|
||||||
{
|
{
|
||||||
return (measurement > 50);
|
return (measurement.value > 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
int QBenchmarkTimeMeasurer::adjustIterationCount(int suggestion)
|
int QBenchmarkTimeMeasurer::adjustIterationCount(int suggestion)
|
||||||
@ -41,11 +41,6 @@ int QBenchmarkTimeMeasurer::adjustMedianCount(int)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::QBenchmarkMetric QBenchmarkTimeMeasurer::metricType()
|
|
||||||
{
|
|
||||||
return QTest::WalltimeMilliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_TICK_COUNTER // defined in 3rdparty/cycle_p.h
|
#ifdef HAVE_TICK_COUNTER // defined in 3rdparty/cycle_p.h
|
||||||
|
|
||||||
void QBenchmarkTickMeasurer::start()
|
void QBenchmarkTickMeasurer::start()
|
||||||
@ -53,13 +48,13 @@ void QBenchmarkTickMeasurer::start()
|
|||||||
startTicks = getticks();
|
startTicks = getticks();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkTickMeasurer::stop()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkTickMeasurer::stop()
|
||||||
{
|
{
|
||||||
CycleCounterTicks now = getticks();
|
CycleCounterTicks now = getticks();
|
||||||
return qRound64(elapsed(now, startTicks));
|
return { elapsed(now, startTicks), QTest::CPUTicks };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QBenchmarkTickMeasurer::isMeasurementAccepted(qint64)
|
bool QBenchmarkTickMeasurer::isMeasurementAccepted(QBenchmarkMeasurerBase::Measurement)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -79,11 +74,6 @@ bool QBenchmarkTickMeasurer::needsWarmupIteration()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::QBenchmarkMetric QBenchmarkTickMeasurer::metricType()
|
|
||||||
{
|
|
||||||
return QTest::CPUTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,15 +23,19 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QBenchmarkMeasurerBase
|
class QBenchmarkMeasurerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Measurement
|
||||||
|
{
|
||||||
|
qreal value;
|
||||||
|
QTest::QBenchmarkMetric metric;
|
||||||
|
};
|
||||||
virtual ~QBenchmarkMeasurerBase() = default;
|
virtual ~QBenchmarkMeasurerBase() = default;
|
||||||
virtual void init() {}
|
virtual void init() {}
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
virtual qint64 stop() = 0;
|
virtual Measurement stop() = 0;
|
||||||
virtual bool isMeasurementAccepted(qint64 measurement) = 0;
|
virtual bool isMeasurementAccepted(Measurement m) = 0;
|
||||||
virtual int adjustIterationCount(int suggestion) = 0;
|
virtual int adjustIterationCount(int suggestion) = 0;
|
||||||
virtual int adjustMedianCount(int suggestion) = 0;
|
virtual int adjustMedianCount(int suggestion) = 0;
|
||||||
virtual bool needsWarmupIteration() { return false; }
|
virtual bool needsWarmupIteration() { return false; }
|
||||||
virtual QTest::QBenchmarkMetric metricType() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -474,14 +474,14 @@ void QBenchmarkPerfEventsMeasurer::start()
|
|||||||
::ioctl(fd, PERF_EVENT_IOC_ENABLE);
|
::ioctl(fd, PERF_EVENT_IOC_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkPerfEventsMeasurer::stop()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkPerfEventsMeasurer::stop()
|
||||||
{
|
{
|
||||||
// disable the counter
|
// disable the counter
|
||||||
::ioctl(fd, PERF_EVENT_IOC_DISABLE);
|
::ioctl(fd, PERF_EVENT_IOC_DISABLE);
|
||||||
return readValue();
|
return readValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QBenchmarkPerfEventsMeasurer::isMeasurementAccepted(qint64)
|
bool QBenchmarkPerfEventsMeasurer::isMeasurementAccepted(Measurement)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -496,11 +496,6 @@ int QBenchmarkPerfEventsMeasurer::adjustMedianCount(int)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::QBenchmarkMetric QBenchmarkPerfEventsMeasurer::metricType()
|
|
||||||
{
|
|
||||||
return metricForEvent(attr.type, attr.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
static quint64 rawReadValue(int fd)
|
static quint64 rawReadValue(int fd)
|
||||||
{
|
{
|
||||||
/* from the kernel docs:
|
/* from the kernel docs:
|
||||||
@ -536,10 +531,10 @@ static quint64 rawReadValue(int fd)
|
|||||||
return results.value * (double(results.time_running) / double(results.time_enabled));
|
return results.value * (double(results.time_running) / double(results.time_enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkPerfEventsMeasurer::readValue()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkPerfEventsMeasurer::readValue()
|
||||||
{
|
{
|
||||||
quint64 raw = rawReadValue(fd);
|
quint64 raw = rawReadValue(fd);
|
||||||
return raw;
|
return { qreal(qint64(raw)), metricForEvent(attr.type, attr.config) };
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -26,12 +26,11 @@ public:
|
|||||||
~QBenchmarkPerfEventsMeasurer();
|
~QBenchmarkPerfEventsMeasurer();
|
||||||
void init() override;
|
void init() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
qint64 stop() override;
|
Measurement stop() override;
|
||||||
bool isMeasurementAccepted(qint64 measurement) override;
|
bool isMeasurementAccepted(Measurement measurement) override;
|
||||||
int adjustIterationCount(int suggestion) override;
|
int adjustIterationCount(int suggestion) override;
|
||||||
int adjustMedianCount(int suggestion) override;
|
int adjustMedianCount(int suggestion) override;
|
||||||
bool needsWarmupIteration() override { return true; }
|
bool needsWarmupIteration() override { return true; }
|
||||||
QTest::QBenchmarkMetric metricType() override;
|
|
||||||
|
|
||||||
static bool isAvailable();
|
static bool isAvailable();
|
||||||
static QTest::QBenchmarkMetric metricForEvent(quint32 type, quint64 event_id);
|
static QTest::QBenchmarkMetric metricForEvent(quint32 type, quint64 event_id);
|
||||||
@ -40,7 +39,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
qint64 readValue();
|
Measurement readValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -25,12 +25,11 @@ class QBenchmarkTimeMeasurer : public QBenchmarkMeasurerBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void start() override;
|
void start() override;
|
||||||
qint64 stop() override;
|
Measurement stop() override;
|
||||||
bool isMeasurementAccepted(qint64 measurement) override;
|
bool isMeasurementAccepted(Measurement measurement) override;
|
||||||
int adjustIterationCount(int sugestion) override;
|
int adjustIterationCount(int sugestion) override;
|
||||||
int adjustMedianCount(int suggestion) override;
|
int adjustMedianCount(int suggestion) override;
|
||||||
bool needsWarmupIteration() override;
|
bool needsWarmupIteration() override;
|
||||||
QTest::QBenchmarkMetric metricType() override;
|
|
||||||
private:
|
private:
|
||||||
QElapsedTimer time;
|
QElapsedTimer time;
|
||||||
};
|
};
|
||||||
@ -41,12 +40,11 @@ class QBenchmarkTickMeasurer : public QBenchmarkMeasurerBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void start() override;
|
void start() override;
|
||||||
qint64 stop() override;
|
Measurement stop() override;
|
||||||
bool isMeasurementAccepted(qint64 measurement) override;
|
bool isMeasurementAccepted(Measurement measurement) override;
|
||||||
int adjustIterationCount(int) override;
|
int adjustIterationCount(int) override;
|
||||||
int adjustMedianCount(int suggestion) override;
|
int adjustMedianCount(int suggestion) override;
|
||||||
bool needsWarmupIteration() override;
|
bool needsWarmupIteration() override;
|
||||||
QTest::QBenchmarkMetric metricType() override;
|
|
||||||
private:
|
private:
|
||||||
CycleCounterTicks startTicks;
|
CycleCounterTicks startTicks;
|
||||||
};
|
};
|
||||||
|
@ -170,14 +170,14 @@ void QBenchmarkCallgrindMeasurer::start()
|
|||||||
CALLGRIND_ZERO_STATS;
|
CALLGRIND_ZERO_STATS;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QBenchmarkCallgrindMeasurer::stop()
|
QBenchmarkMeasurerBase::Measurement QBenchmarkCallgrindMeasurer::stop()
|
||||||
{
|
{
|
||||||
CALLGRIND_DUMP_STATS;
|
CALLGRIND_DUMP_STATS;
|
||||||
const qint64 result = QBenchmarkValgrindUtils::extractLastResult();
|
const qint64 result = QBenchmarkValgrindUtils::extractLastResult();
|
||||||
return result;
|
return { qreal(result), QTest::InstructionReads };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QBenchmarkCallgrindMeasurer::isMeasurementAccepted(qint64 measurement)
|
bool QBenchmarkCallgrindMeasurer::isMeasurementAccepted(Measurement measurement)
|
||||||
{
|
{
|
||||||
Q_UNUSED(measurement);
|
Q_UNUSED(measurement);
|
||||||
return true;
|
return true;
|
||||||
@ -198,9 +198,4 @@ bool QBenchmarkCallgrindMeasurer::needsWarmupIteration()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTest::QBenchmarkMetric QBenchmarkCallgrindMeasurer::metricType()
|
|
||||||
{
|
|
||||||
return QTest::InstructionReads;
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -41,12 +41,11 @@ class QBenchmarkCallgrindMeasurer : public QBenchmarkMeasurerBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void start() override;
|
void start() override;
|
||||||
qint64 stop() override;
|
Measurement stop() override;
|
||||||
bool isMeasurementAccepted(qint64 measurement) override;
|
bool isMeasurementAccepted(Measurement measurement) override;
|
||||||
int adjustIterationCount(int) override;
|
int adjustIterationCount(int) override;
|
||||||
int adjustMedianCount(int) override;
|
int adjustMedianCount(int) override;
|
||||||
bool needsWarmupIteration() override;
|
bool needsWarmupIteration() override;
|
||||||
QTest::QBenchmarkMetric metricType() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user