summaryrefslogtreecommitdiffstats
path: root/src/concurrent/qtconcurrentiteratekernel.cpp
diff options
context:
space:
mode:
authorTobias Koenig <tobias.koenig@kdab.com>2016-01-19 17:45:42 +0100
committerTobias Koenig <tobias.koenig@kdab.com>2016-01-21 18:57:04 +0000
commit24d851dcd2a140bf346343c5eb64d944cd1c1a87 (patch)
treec298808e3d9b41fe36a88106bc957d5b6e1910aa /src/concurrent/qtconcurrentiteratekernel.cpp
parentc3850dd636ab24c251942fde63f22d8f5b3a639e (diff)
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 <marc.mutz@kdab.com>
Diffstat (limited to 'src/concurrent/qtconcurrentiteratekernel.cpp')
-rw-r--r--src/concurrent/qtconcurrentiteratekernel.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp
index 49056406c3..3b9b186b39 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