summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2020-09-16 16:46:18 -0700
committerThiago Macieira <thiago.macieira@intel.com>2020-10-18 10:45:29 -0700
commit009656229943445e73225eb4b5d7975454cf0b63 (patch)
tree82b04ba549b19e66c61f7c70062c691313022f14 /src
parentd0c4d18b01279869123a36bdbbd65571a6745fc7 (diff)
QRandomGenerator: optimize for the common use case
The most common uses of QRandomGenerator are getting 32- and 64-bit quantities, either through the generate() and generate64() functions or by ones that call those, like bounded() or generateDouble(). So optimize for those with the same entry point by returning one 64-bit value from the _fillRange() function. Further optimize by not requiring a buffer for those two cases, which required us to replace the (begin, end) parameters with (begin, count). Change-Id: I3eb349b832c14610895efffd16356859eecd5397 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qrandom.cpp34
-rw-r--r--src/corelib/global/qrandom.h18
2 files changed, 29 insertions, 23 deletions
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 6a0b86dd6e..9a6e781b99 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 Intel Corporation.
+** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -1177,22 +1177,32 @@ bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
/*!
\internal
- Fills the range pointed by \a buffer and \a bufferEnd with 32-bit random
- values. The buffer must be correctly aligned.
+ Fills the range pointed by \a buffer with \a count 32-bit random values.
+ The buffer must be correctly aligned.
+
+ Returns the value of the first two 32-bit entries as a \c{quint64}.
*/
-void QRandomGenerator::_fillRange(void *buffer, void *bufferEnd)
+quint64 QRandomGenerator::_fillRange(void *buffer, qptrdiff count)
{
// Verify that the pointers are properly aligned for 32-bit
Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0);
- Q_ASSERT(quintptr(bufferEnd) % sizeof(quint32) == 0);
- quint32 *begin = static_cast<quint32 *>(buffer);
- quint32 *end = static_cast<quint32 *>(bufferEnd);
-
- if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData)))
- return SystemGenerator::self().generate(begin, end);
+ Q_ASSERT(count >= 0);
+ Q_ASSERT(buffer || count <= 2);
+
+ quint64 dummy;
+ quint32 *begin = static_cast<quint32 *>(buffer ? buffer : &dummy);
+ quint32 *end = begin + count;
+
+ if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData))) {
+ SystemGenerator::self().generate(begin, end);
+ } else {
+ SystemAndGlobalGenerators::PRNGLocker lock(this);
+ std::generate(begin, end, [this]() { return storage.engine()(); });
+ }
- SystemAndGlobalGenerators::PRNGLocker lock(this);
- std::generate(begin, end, [this]() { return storage.engine()(); });
+ if (end - begin == 1)
+ return *begin;
+ return begin[0] | (quint64(begin[1]) << 32);
}
namespace {
diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h
index 7bb90de2bb..29cb24d1f5 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -83,16 +83,12 @@ public:
quint32 generate()
{
- quint32 ret;
- fillRange(&ret, 1);
- return ret;
+ return _fillRange(nullptr, 1);
}
quint64 generate64()
{
- quint32 buf[2];
- fillRange(buf);
- return buf[0] | (quint64(buf[1]) << 32);
+ return _fillRange(nullptr, sizeof(quint64) / sizeof(quint32));
}
double generateDouble()
@@ -142,13 +138,13 @@ public:
template <typename UInt, IfValidUInt<UInt> = true>
void fillRange(UInt *buffer, qsizetype count)
{
- _fillRange(buffer, buffer + count);
+ _fillRange(buffer, count * sizeof(UInt) / sizeof(quint32));
}
template <typename UInt, size_t N, IfValidUInt<UInt> = true>
void fillRange(UInt (&buffer)[N])
{
- _fillRange(buffer, buffer + N);
+ _fillRange(buffer, N * sizeof(UInt) / sizeof(quint32));
}
// API like std::seed_seq
@@ -160,7 +156,7 @@ public:
void generate(quint32 *begin, quint32 *end)
{
- _fillRange(begin, end);
+ _fillRange(begin, end - begin);
}
// API like std:: random engines
@@ -181,7 +177,7 @@ protected:
QRandomGenerator(System);
private:
- Q_CORE_EXPORT void _fillRange(void *buffer, void *bufferEnd);
+ Q_CORE_EXPORT quint64 _fillRange(void *buffer, qptrdiff count);
friend class QRandomGenerator64;
struct SystemGenerator;