summaryrefslogtreecommitdiffstats
path: root/src/concurrent/qtconcurrentiteratekernel.cpp
blob: 00228f181cbd0c5c962458af8fcfffb86d40159f (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
// Copyright (C) 2016 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#include"qtconcurrentiteratekernel.h"#include <qdeadlinetimer.h>#include"private/qfunctions_p.h"#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC) QT_BEGIN_NAMESPACE enum{ TargetRatio =100};static qint64 getticks(){returnQDeadlineTimer::current(Qt::PreciseTimer).deadlineNSecs();}static doubleelapsed(qint64 after, qint64 before){returndouble(after - before);}namespace QtConcurrent {/*! \class QtConcurrent::Median \inmodule QtConcurrent \internal *//*! \class QtConcurrent::BlockSizeManager \inmodule QtConcurrent \internal *//*! \class QtConcurrent::ResultReporter \inmodule QtConcurrent \internal *//*! \fn bool QtConcurrent::selectIteration(std::bidirectional_iterator_tag) \internal *//*! \fn bool QtConcurrent::selectIteration(std::forward_iterator_tag) \internal *//*! \fn bool QtConcurrent::selectIteration(std::random_access_iterator_tag) \internal *//*! \class QtConcurrent::IterateKernel \inmodule QtConcurrent \internal *//*! \internal*/BlockSizeManager::BlockSizeManager(QThreadPool *pool,int iterationCount):maxBlockSize(iterationCount / (std::max(pool->maxThreadCount(),1) *2)),beforeUser(0),afterUser(0),m_blockSize(1){ }// Records the time before user code.voidBlockSizeManager::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.voidBlockSizeManager::timeAfterUser(){if(blockSizeMaxed())return; afterUser =getticks(); userPartElapsed.addValue(elapsed(afterUser, beforeUser));if(controlPartElapsed.isMedianValid() ==false)return;if(controlPartElapsed.median() *int(TargetRatio) < userPartElapsed.median())return; m_blockSize =qMin(m_blockSize *2, maxBlockSize);#ifdef QTCONCURRENT_FOR_DEBUGqDebug() <<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();}intBlockSizeManager::blockSize(){return m_blockSize;}}// namespace QtConcurrent QT_END_NAMESPACE #endif// QT_NO_CONCURRENT
close