Skip to content

Commit

Permalink
Merge pull request #1215 from etiennesky/mtr_maxcpus
Browse files Browse the repository at this point in the history
[FEATURE] add option to set max thread count
  • Loading branch information
wonder-sk committed May 22, 2014
2 parents dac4cfc + a4e974a commit 35f55e8
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/app/main.cpp
Expand Up @@ -873,6 +873,10 @@ int main( int argc, char *argv[] )
mySettings.remove( "/qgis/restoreDefaultWindowState" );
}

// set max. thread count
// this should be done in QgsApplication::init() but it doesn't know the settings dir.
QgsApplication::setMaxThreads( QSettings().value( "/qgis/max_threads", -1 ).toInt() );

QgisApp *qgis = new QgisApp( mypSplash, myRestorePlugins ); // "QgisApp" used to find canonical instance
qgis->setObjectName( "QgisApp" );

Expand Down
8 changes: 8 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -547,6 +547,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );
chkParallelRendering->setChecked( settings.value( "/qgis/parallel_rendering", false ).toBool() );
spinMapUpdateInterval->setValue( settings.value( "/qgis/map_update_interval", 250 ).toInt() );
chkMaxThreads->setChecked( QgsApplication::maxThreads() != -1 );
spinMaxThreads->setEnabled( chkMaxThreads->isChecked() );
spinMaxThreads->setRange( 1, QThread::idealThreadCount() );
spinMaxThreads->setValue( QgsApplication::maxThreads() );

// Default simplify drawing configuration
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", ( int )QgsVectorSimplifyMethod::GeometrySimplification ).toInt() != QgsVectorSimplifyMethod::NoSimplification );
Expand Down Expand Up @@ -1071,6 +1075,10 @@ void QgsOptions::saveOptions()
settings.setValue( "/qgis/enable_anti_aliasing", chkAntiAliasing->isChecked() );
settings.setValue( "/qgis/enable_render_caching", chkUseRenderCaching->isChecked() );
settings.setValue( "/qgis/parallel_rendering", chkParallelRendering->isChecked() );
int maxThreads = chkMaxThreads->isChecked() ? spinMaxThreads->value() : -1;
QgsApplication::setMaxThreads( maxThreads );
settings.setValue( "/qgis/max_threads", maxThreads );

settings.setValue( "/qgis/map_update_interval", spinMapUpdateInterval->value() );
settings.setValue( "/qgis/legendDoubleClickAction", cmbLegendDoubleClickAction->currentIndex() );
bool legendLayersCapitalise = settings.value( "/qgis/capitaliseLayerName", false ).toBool();
Expand Down
27 changes: 27 additions & 0 deletions src/core/qgsapplication.cpp
Expand Up @@ -29,6 +29,7 @@
#include <QSettings>
#include <QIcon>
#include <QPixmap>
#include <QThreadPool>

#ifndef Q_WS_WIN
#include <netinet/in.h>
Expand Down Expand Up @@ -61,6 +62,7 @@ QString ABISYM( QgsApplication::mCfgIntDir );
#endif
QString ABISYM( QgsApplication::mBuildOutputPath );
QStringList ABISYM( QgsApplication::mGdalSkipList );
int ABISYM( QgsApplication::mMaxThreads );

/*!
\class QgsApplication
Expand Down Expand Up @@ -181,6 +183,11 @@ void QgsApplication::init( QString customConfigPath )

// allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
QCoreApplication::addLibraryPath( pluginPath() );

// set max. thread count to -1
// this should be read from QSettings but we don't know where they are at this point
// so we read actual value in main.cpp
ABISYM( mMaxThreads ) = -1;
}

QgsApplication::~QgsApplication()
Expand Down Expand Up @@ -1016,4 +1023,24 @@ bool QgsApplication::createDB( QString *errorMessage )
return true;
}

void QgsApplication::setMaxThreads( int maxThreads )
{
QgsDebugMsg( QString( "maxThreads: %1" ).arg( maxThreads ) );

// make sure value is between 1 and #cores, if not set to -1 (use #cores)
// 0 could be used to disable any parallel processing
if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
maxThreads = -1;

// save value
ABISYM( mMaxThreads ) = maxThreads;

// if -1 use #cores
if ( maxThreads == -1 )
maxThreads = QThread::idealThreadCount();

// set max thread count in QThreadPool
QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
QgsDebugMsg( QString( "set QThreadPool max thread count to %d" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
}

11 changes: 11 additions & 0 deletions src/core/qgsapplication.h
Expand Up @@ -279,6 +279,14 @@ class CORE_EXPORT QgsApplication : public QApplication
* @note added in 2.0 */
static void applyGdalSkippedDrivers();

/** Get maximum concurrent thread count
* @note added in 2.4 */
static int maxThreads() { return ABISYM( mMaxThreads ); }
/** Set maximum concurrent thread count
* @note must be between 1 and #cores, -1 means use all available cores
* @note added in 2.4 */
static void setMaxThreads( int maxThreads );

#ifdef ANDROID
//dummy method to workaround sip generation issue issue
bool x11EventFilter( XEvent * event )
Expand Down Expand Up @@ -320,6 +328,9 @@ class CORE_EXPORT QgsApplication : public QApplication
* @see skipGdalDriver, restoreGdalDriver
* @note added in 2.0 */
static QStringList ABISYM( mGdalSkipList );
/**
* @note added in 2.4 */
static int ABISYM( mMaxThreads );
};

#endif
3 changes: 3 additions & 0 deletions src/core/qgsmaprendererjob.cpp
Expand Up @@ -5,6 +5,7 @@
#include <QTime>
#include <QTimer>
#include <QtConcurrentMap>
#include <QSettings>

#include "qgscrscache.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -731,6 +732,8 @@ void QgsMapRendererParallelJob::start()

mLayerJobs = prepareJobs( 0, mLabelingEngine );

qDebug( "QThreadPool max thread count is %d", QThreadPool::globalInstance()->maxThreadCount() );

// start async job

connect( &mFutureWatcher, SIGNAL( finished() ), SLOT( renderLayersFinished() ) );
Expand Down
60 changes: 55 additions & 5 deletions src/ui/qgsoptionsbase.ui
Expand Up @@ -1629,11 +1629,45 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkParallelRendering">
<property name="text">
<string>Render layers in parallel using all available CPU cores</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_26">
<item>
<widget class="QCheckBox" name="chkParallelRendering">
<property name="text">
<string>Render layers in parallel using many CPU cores</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkMaxThreads">
<property name="text">
<string>Max cores to use:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinMaxThreads"/>
</item>
<item>
<spacer name="horizontalSpacer_41">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
Expand Down Expand Up @@ -4598,5 +4632,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>chkMaxThreads</sender>
<signal>toggled(bool)</signal>
<receiver>spinMaxThreads</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>589</x>
<y>110</y>
</hint>
<hint type="destinationlabel">
<x>689</x>
<y>110</y>
</hint>
</hints>
</connection>
</connections>
</ui>

0 comments on commit 35f55e8

Please sign in to comment.