From 24d851dcd2a140bf346343c5eb64d944cd1c1a87 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 Jan 2016 17:45:42 +0100 Subject: Avoid heap allocations in Median class Create a MedianDouble class and V2 version of BlockSizeManager, which use a fixed size array of double (since we always use 7 elements to calculate the median anyway). Change-Id: Ife90b90336a9a8c037b90726dee4cd2a1b8b6cd9 Reviewed-by: Marc Mutz --- src/concurrent/qtconcurrentiteratekernel.cpp | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/concurrent/qtconcurrentiteratekernel.cpp') diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp index 49056406c30..3b9b186b397 100644 --- a/src/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/concurrent/qtconcurrentiteratekernel.cpp @@ -182,6 +182,58 @@ int BlockSizeManager::blockSize() return m_blockSize; } +/*! \internal + +*/ +BlockSizeManagerV2::BlockSizeManagerV2(int iterationCount) + : maxBlockSize(iterationCount / (QThreadPool::globalInstance()->maxThreadCount() * 2)), + beforeUser(0), afterUser(0), + m_blockSize(1) +{ } + +// Records the time before user code. +void BlockSizeManagerV2::timeBeforeUser() +{ + if (blockSizeMaxed()) + return; + + beforeUser = getticks(); + controlPartElapsed.addValue(elapsed(beforeUser, afterUser)); +} + + // Records the time after user code and adjust the block size if we are spending + // to much time in the for control code compared with the user code. +void BlockSizeManagerV2::timeAfterUser() +{ + if (blockSizeMaxed()) + return; + + afterUser = getticks(); + userPartElapsed.addValue(elapsed(afterUser, beforeUser)); + + if (controlPartElapsed.isMedianValid() == false) + return; + + if (controlPartElapsed.median() * TargetRatio < userPartElapsed.median()) + return; + + m_blockSize = qMin(m_blockSize * 2, maxBlockSize); + +#ifdef QTCONCURRENT_FOR_DEBUG + qDebug() << QThread::currentThread() << "adjusting block size" << controlPartElapsed.median() << userPartElapsed.median() << m_blockSize; +#endif + + // Reset the medians after adjusting the block size so we get + // new measurements with the new block size. + controlPartElapsed.reset(); + userPartElapsed.reset(); +} + +int BlockSizeManagerV2::blockSize() +{ + return m_blockSize; +} + } // namespace QtConcurrent QT_END_NAMESPACE -- cgit v1.2.3