Skip to content

Commit 35f55e8

Browse files
committed
Merge pull request #1215 from etiennesky/mtr_maxcpus
[FEATURE] add option to set max thread count
2 parents dac4cfc + a4e974a commit 35f55e8

6 files changed

Lines changed: 108 additions & 5 deletions

File tree

‎src/app/main.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,10 @@ int main( int argc, char *argv[] )
873873
mySettings.remove( "/qgis/restoreDefaultWindowState" );
874874
}
875875

876+
// set max. thread count
877+
// this should be done in QgsApplication::init() but it doesn't know the settings dir.
878+
QgsApplication::setMaxThreads( QSettings().value( "/qgis/max_threads", -1 ).toInt() );
879+
876880
QgisApp *qgis = new QgisApp( mypSplash, myRestorePlugins ); // "QgisApp" used to find canonical instance
877881
qgis->setObjectName( "QgisApp" );
878882

‎src/app/qgsoptions.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
547547
chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );
548548
chkParallelRendering->setChecked( settings.value( "/qgis/parallel_rendering", false ).toBool() );
549549
spinMapUpdateInterval->setValue( settings.value( "/qgis/map_update_interval", 250 ).toInt() );
550+
chkMaxThreads->setChecked( QgsApplication::maxThreads() != -1 );
551+
spinMaxThreads->setEnabled( chkMaxThreads->isChecked() );
552+
spinMaxThreads->setRange( 1, QThread::idealThreadCount() );
553+
spinMaxThreads->setValue( QgsApplication::maxThreads() );
550554

551555
// Default simplify drawing configuration
552556
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", ( int )QgsVectorSimplifyMethod::GeometrySimplification ).toInt() != QgsVectorSimplifyMethod::NoSimplification );
@@ -1071,6 +1075,10 @@ void QgsOptions::saveOptions()
10711075
settings.setValue( "/qgis/enable_anti_aliasing", chkAntiAliasing->isChecked() );
10721076
settings.setValue( "/qgis/enable_render_caching", chkUseRenderCaching->isChecked() );
10731077
settings.setValue( "/qgis/parallel_rendering", chkParallelRendering->isChecked() );
1078+
int maxThreads = chkMaxThreads->isChecked() ? spinMaxThreads->value() : -1;
1079+
QgsApplication::setMaxThreads( maxThreads );
1080+
settings.setValue( "/qgis/max_threads", maxThreads );
1081+
10741082
settings.setValue( "/qgis/map_update_interval", spinMapUpdateInterval->value() );
10751083
settings.setValue( "/qgis/legendDoubleClickAction", cmbLegendDoubleClickAction->currentIndex() );
10761084
bool legendLayersCapitalise = settings.value( "/qgis/capitaliseLayerName", false ).toBool();

‎src/core/qgsapplication.cpp‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <QSettings>
3030
#include <QIcon>
3131
#include <QPixmap>
32+
#include <QThreadPool>
3233

3334
#ifndef Q_WS_WIN
3435
#include <netinet/in.h>
@@ -61,6 +62,7 @@ QString ABISYM( QgsApplication::mCfgIntDir );
6162
#endif
6263
QString ABISYM( QgsApplication::mBuildOutputPath );
6364
QStringList ABISYM( QgsApplication::mGdalSkipList );
65+
int ABISYM( QgsApplication::mMaxThreads );
6466

6567
/*!
6668
\class QgsApplication
@@ -181,6 +183,11 @@ void QgsApplication::init( QString customConfigPath )
181183

182184
// allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
183185
QCoreApplication::addLibraryPath( pluginPath() );
186+
187+
// set max. thread count to -1
188+
// this should be read from QSettings but we don't know where they are at this point
189+
// so we read actual value in main.cpp
190+
ABISYM( mMaxThreads ) = -1;
184191
}
185192

186193
QgsApplication::~QgsApplication()
@@ -1016,4 +1023,24 @@ bool QgsApplication::createDB( QString *errorMessage )
10161023
return true;
10171024
}
10181025

1026+
void QgsApplication::setMaxThreads( int maxThreads )
1027+
{
1028+
QgsDebugMsg( QString( "maxThreads: %1" ).arg( maxThreads ) );
1029+
1030+
// make sure value is between 1 and #cores, if not set to -1 (use #cores)
1031+
// 0 could be used to disable any parallel processing
1032+
if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
1033+
maxThreads = -1;
1034+
1035+
// save value
1036+
ABISYM( mMaxThreads ) = maxThreads;
1037+
1038+
// if -1 use #cores
1039+
if ( maxThreads == -1 )
1040+
maxThreads = QThread::idealThreadCount();
1041+
1042+
// set max thread count in QThreadPool
1043+
QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
1044+
QgsDebugMsg( QString( "set QThreadPool max thread count to %d" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
1045+
}
10191046

‎src/core/qgsapplication.h‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ class CORE_EXPORT QgsApplication : public QApplication
279279
* @note added in 2.0 */
280280
static void applyGdalSkippedDrivers();
281281

282+
/** Get maximum concurrent thread count
283+
* @note added in 2.4 */
284+
static int maxThreads() { return ABISYM( mMaxThreads ); }
285+
/** Set maximum concurrent thread count
286+
* @note must be between 1 and #cores, -1 means use all available cores
287+
* @note added in 2.4 */
288+
static void setMaxThreads( int maxThreads );
289+
282290
#ifdef ANDROID
283291
//dummy method to workaround sip generation issue issue
284292
bool x11EventFilter( XEvent * event )
@@ -320,6 +328,9 @@ class CORE_EXPORT QgsApplication : public QApplication
320328
* @see skipGdalDriver, restoreGdalDriver
321329
* @note added in 2.0 */
322330
static QStringList ABISYM( mGdalSkipList );
331+
/**
332+
* @note added in 2.4 */
333+
static int ABISYM( mMaxThreads );
323334
};
324335

325336
#endif

‎src/core/qgsmaprendererjob.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <QTime>
66
#include <QTimer>
77
#include <QtConcurrentMap>
8+
#include <QSettings>
89

910
#include "qgscrscache.h"
1011
#include "qgslogger.h"
@@ -731,6 +732,8 @@ void QgsMapRendererParallelJob::start()
731732

732733
mLayerJobs = prepareJobs( 0, mLabelingEngine );
733734

735+
qDebug( "QThreadPool max thread count is %d", QThreadPool::globalInstance()->maxThreadCount() );
736+
734737
// start async job
735738

736739
connect( &mFutureWatcher, SIGNAL( finished() ), SLOT( renderLayersFinished() ) );

‎src/ui/qgsoptionsbase.ui‎

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,11 +1629,45 @@
16291629
</widget>
16301630
</item>
16311631
<item>
1632-
<widget class="QCheckBox" name="chkParallelRendering">
1633-
<property name="text">
1634-
<string>Render layers in parallel using all available CPU cores</string>
1635-
</property>
1636-
</widget>
1632+
<layout class="QHBoxLayout" name="horizontalLayout_26">
1633+
<item>
1634+
<widget class="QCheckBox" name="chkParallelRendering">
1635+
<property name="text">
1636+
<string>Render layers in parallel using many CPU cores</string>
1637+
</property>
1638+
</widget>
1639+
</item>
1640+
<item>
1641+
<widget class="Line" name="line_6">
1642+
<property name="orientation">
1643+
<enum>Qt::Vertical</enum>
1644+
</property>
1645+
</widget>
1646+
</item>
1647+
<item>
1648+
<widget class="QCheckBox" name="chkMaxThreads">
1649+
<property name="text">
1650+
<string>Max cores to use:</string>
1651+
</property>
1652+
</widget>
1653+
</item>
1654+
<item>
1655+
<widget class="QSpinBox" name="spinMaxThreads"/>
1656+
</item>
1657+
<item>
1658+
<spacer name="horizontalSpacer_41">
1659+
<property name="orientation">
1660+
<enum>Qt::Horizontal</enum>
1661+
</property>
1662+
<property name="sizeHint" stdset="0">
1663+
<size>
1664+
<width>40</width>
1665+
<height>20</height>
1666+
</size>
1667+
</property>
1668+
</spacer>
1669+
</item>
1670+
</layout>
16371671
</item>
16381672
<item>
16391673
<layout class="QHBoxLayout" name="horizontalLayout_4">
@@ -4598,5 +4632,21 @@
45984632
</hint>
45994633
</hints>
46004634
</connection>
4635+
<connection>
4636+
<sender>chkMaxThreads</sender>
4637+
<signal>toggled(bool)</signal>
4638+
<receiver>spinMaxThreads</receiver>
4639+
<slot>setEnabled(bool)</slot>
4640+
<hints>
4641+
<hint type="sourcelabel">
4642+
<x>589</x>
4643+
<y>110</y>
4644+
</hint>
4645+
<hint type="destinationlabel">
4646+
<x>689</x>
4647+
<y>110</y>
4648+
</hint>
4649+
</hints>
4650+
</connection>
46014651
</connections>
46024652
</ui>

0 commit comments

Comments
 (0)