From 94210d2e69ba10f22d1530c6b1e780867c5bfac0 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 31 Aug 2016 14:58:53 -0700 Subject: [PATCH] Use dynamic count for global thread pool --- interface/src/Application.cpp | 21 ++++++++++++++++--- interface/src/Application.h | 1 + .../src/display-plugins/OpenGLDisplayPlugin.h | 2 ++ libraries/plugins/src/plugins/DisplayPlugin.h | 1 + plugins/openvr/src/OpenVrDisplayPlugin.h | 3 +++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d846a5c6d1..45feed1088 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -176,8 +176,6 @@ static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; // For processing on QThreadPool, target 2 less than the ideal number of threads, leaving // 2 logical cores available for time sensitive tasks. static const int MIN_PROCESSING_THREAD_POOL_SIZE = 2; -static const int PROCESSING_THREAD_POOL_SIZE = std::max(MIN_PROCESSING_THREAD_POOL_SIZE, - QThread::idealThreadCount() - 2); static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; @@ -537,7 +535,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : PluginContainer* pluginContainer = dynamic_cast(this); // set the container for any plugins that care PluginManager::getInstance()->setContainer(pluginContainer); - QThreadPool::globalInstance()->setMaxThreadCount(PROCESSING_THREAD_POOL_SIZE); + QThreadPool::globalInstance()->setMaxThreadCount(MIN_PROCESSING_THREAD_POOL_SIZE); thread()->setPriority(QThread::HighPriority); thread()->setObjectName("Main Thread"); @@ -707,6 +705,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress); + connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount); + // Save avatar location immediately after a teleport. connect(getMyAvatar(), &MyAvatar::positionGoneTo, DependencyManager::get().data(), &AddressManager::storeCurrentAddress); @@ -5727,3 +5727,18 @@ void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) { EntityItemID entityItemID(id); emit getEntities()->hoverLeaveEntity(entityItemID, event); } + +// FIXME? perhaps two, one for the main thread and one for the offscreen UI rendering thread? +static const int UI_RESERVED_THREADS = 1; +// Windows won't let you have all the cores +static const int OS_RESERVED_THREADS = 1; + +void Application::updateThreadPoolCount() const { + auto reservedThreads = UI_RESERVED_THREADS + OS_RESERVED_THREADS + _displayPlugin->getRequiredThreadCount(); + auto availableThreads = QThread::idealThreadCount() - reservedThreads; + auto threadPoolSize = std::max(MIN_PROCESSING_THREAD_POOL_SIZE, availableThreads); + qDebug() << "Ideal Thread Count " << QThread::idealThreadCount(); + qDebug() << "Reserved threads " << reservedThreads; + qDebug() << "Setting thread pool size to " << threadPoolSize; + QThreadPool::globalInstance()->setMaxThreadCount(threadPoolSize); +} \ No newline at end of file diff --git a/interface/src/Application.h b/interface/src/Application.h index a0c67a9e73..8bfae51179 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -286,6 +286,7 @@ public slots: bool exportEntities(const QString& filename, const QVector& entityIDs, const glm::vec3* givenOffset = nullptr); bool exportEntities(const QString& filename, float x, float y, float z, float scale); bool importEntities(const QString& url); + void updateThreadPoolCount() const; static void setLowVelocityFilter(bool lowVelocityFilter); Q_INVOKABLE void loadDialog(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index afd8f7d45b..ef15861843 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -69,6 +69,8 @@ public: virtual bool wantVsync() const { return true; } void setVsyncEnabled(bool vsyncEnabled) { _vsyncEnabled = vsyncEnabled; } bool isVsyncEnabled() const { return _vsyncEnabled; } + // Three threads, one for rendering, one for texture transfers, one reserved for the GL driver + int getRequiredThreadCount() const override { return 3; } protected: friend class PresentThread; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 5111bda95f..eac08716a1 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -128,6 +128,7 @@ public: Present = QEvent::User + 1 }; + virtual int getRequiredThreadCount() const { return 0; } virtual bool isHmd() const { return false; } virtual int getHmdScreen() const { return -1; } /// By default, all HMDs are stereo diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 75f8c51b0e..025f879d84 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,6 +58,9 @@ public: void unsuppressKeyboard() override; bool isKeyboardVisible() override; + // Needs an additional thread for VR submission + int getRequiredThreadCount() const override { return Parent::getRequiredThreadCount() + 1; } + protected: bool internalActivate() override; void internalDeactivate() override;