Skip to content

Commit ce15429

Browse files
committed
ENH: renaming NumberOfThreads into NumberOfWorkUnits in MultiThreaderBase
Also expose work units in domain threader Change-Id: I1dcf581a41fdcfeb04649dae21552f6d66a64a3e
1 parent 38f516d commit ce15429

67 files changed

Lines changed: 642 additions & 495 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Modules/Core/Common/include/itkDomainThreader.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace itk
4848
* Since a threaded operation is relatively complex compared to a simple serial
4949
* operation, a class instead of a simple method is required. Inside this
5050
* class, the method to partition the data is handled, the logic for
51-
* determining the number of threads is determined, and operations surrounding
51+
* deciding the number of work units is determined, and operations surrounding
5252
* the threading are encapsulated into the class with the
5353
* \c DetermineNumberOfWorkUnitsToUse, \c BeforeThreadedExecution, \c ThreadedExecution,
5454
* and \c AfterThreadedExecution virtual methods.
@@ -90,22 +90,35 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object
9090
void Execute( AssociateType * enclosingClass, const DomainType & domain );
9191

9292
/** Set/Get the DomainPartitioner. */
93-
itkSetObjectMacro( DomainPartitioner, DomainPartitionerType );
94-
itkGetModifiableObjectMacro(DomainPartitioner, DomainPartitionerType );
93+
itkSetObjectMacro( DomainPartitioner, DomainPartitionerType );
94+
itkGetModifiableObjectMacro( DomainPartitioner, DomainPartitionerType );
9595

96-
/** Accessor for number of threads that were actually used in the last
96+
/** Accessor for number of work units that were actually used in the last
9797
* ThreadedExecution. */
9898
itkGetConstMacro( NumberOfWorkUnitsUsed, ThreadIdType );
9999

100100
/** Return the multithreader used by this class. */
101101
MultiThreaderBase * GetMultiThreader() const;
102102

103-
/** Convenience methods to set/get the maximum number of work units to use.
104-
* \warning When setting the maximum number of work units, it will be clamped by
105-
* itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() and ITK_MAX_THREADS.
103+
/** Convenience methods to set/get the desired number of work units to use.
104+
* \warning When setting the desired number of work units, it might be clamped by
105+
* itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads().
106106
* */
107-
ThreadIdType GetMaximumNumberOfThreads() const;
108-
void SetMaximumNumberOfThreads( const ThreadIdType threads );
107+
ThreadIdType GetNumberOfWorkUnits() const
108+
{
109+
return this->m_MultiThreader->GetNumberOfWorkUnits();
110+
}
111+
void SetNumberOfWorkUnits( const ThreadIdType workUnits );
112+
113+
/** Convenience methods to set/get the maximum number of threads to use.
114+
* \warning When setting the maximum number of threads, it will be clamped by
115+
* itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads().
116+
* */
117+
ThreadIdType GetMaximumNumberOfThreads() const
118+
{
119+
return this->m_MultiThreader->GetMaximumNumberOfThreads();
120+
}
121+
void SetMaximumNumberOfThreads(const ThreadIdType threads);
109122

110123
protected:
111124
DomainThreader();
@@ -154,7 +167,7 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object
154167
DomainThreader * domainThreader;
155168
};
156169

157-
/** Store the actual number of threads used, which may be less than
170+
/** Store the actual number of work units used, which may be less than
158171
* the number allocated by the threader if the object does not split
159172
* well into that number.
160173
* This value is determined at the beginning of \c Execute(). */

Modules/Core/Common/include/itkDomainThreader.hxx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,15 @@ DomainThreader< TDomainPartitioner, TAssociate >
4848
}
4949

5050
template< typename TDomainPartitioner, typename TAssociate >
51-
ThreadIdType
51+
void
5252
DomainThreader< TDomainPartitioner, TAssociate >
53-
::GetMaximumNumberOfThreads() const
53+
::SetNumberOfWorkUnits( const ThreadIdType workUnits )
5454
{
55-
return this->m_MultiThreader->GetNumberOfThreads();
55+
if( workUnits != this->GetNumberOfWorkUnits() )
56+
{
57+
this->m_MultiThreader->SetNumberOfWorkUnits( workUnits );
58+
this->Modified();
59+
};
5660
}
5761

5862
template< typename TDomainPartitioner, typename TAssociate >
@@ -62,7 +66,7 @@ DomainThreader< TDomainPartitioner, TAssociate >
6266
{
6367
if( threads != this->GetMaximumNumberOfThreads() )
6468
{
65-
this->m_MultiThreader->SetNumberOfThreads( threads );
69+
this->m_MultiThreader->SetMaximumNumberOfThreads( threads );
6670
this->Modified();
6771
}
6872
}
@@ -90,7 +94,7 @@ void
9094
DomainThreader< TDomainPartitioner, TAssociate >
9195
::DetermineNumberOfWorkUnitsUsed()
9296
{
93-
const ThreadIdType threaderNumberOfThreads = this->GetMultiThreader()->GetNumberOfThreads();
97+
const ThreadIdType threaderNumberOfThreads = this->GetMultiThreader()->GetNumberOfWorkUnits();
9498

9599
// Attempt a single dummy partition, just to get the number of subdomains actually created
96100
DomainType subdomain;
@@ -102,10 +106,10 @@ DomainThreader< TDomainPartitioner, TAssociate >
102106
if( this->m_NumberOfWorkUnitsUsed < threaderNumberOfThreads )
103107
{
104108
// If PartitionDomain is only able to create a lesser number of subdomains,
105-
// ensure that superfluous threads aren't created
109+
// ensure that superfluous work units aren't created
106110
// DomainThreader::SetMaximumNumberOfThreads *should* already have been called by this point,
107111
// but it's not fatal if it somehow gets called later
108-
this->GetMultiThreader()->SetNumberOfThreads(this->m_NumberOfWorkUnitsUsed);
112+
this->GetMultiThreader()->SetNumberOfWorkUnits(this->m_NumberOfWorkUnitsUsed);
109113
}
110114
else if( this->m_NumberOfWorkUnitsUsed > threaderNumberOfThreads )
111115
{
@@ -135,11 +139,11 @@ ITK_THREAD_RETURN_TYPE
135139
DomainThreader< TDomainPartitioner, TAssociate >
136140
::ThreaderCallback( void* arg )
137141
{
138-
auto * info = static_cast<MultiThreaderBase::ThreadInfoStruct *>(arg);
142+
auto * info = static_cast<MultiThreaderBase::WorkUnitInfo *>(arg);
139143
auto * str = static_cast<ThreadStruct *>(info->UserData);
140144
DomainThreader *thisDomainThreader = str->domainThreader;
141-
const ThreadIdType threadId = info->ThreadID;
142-
const ThreadIdType threadCount = info->NumberOfThreads;
145+
const ThreadIdType threadId = info->WorkUnitID;
146+
const ThreadIdType threadCount = info->NumberOfWorkUnits;
143147

144148
// Get the sub-domain to process for this thread.
145149
DomainType subdomain;

Modules/Core/Common/include/itkImageSource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ class ITK_TEMPLATE_EXPORT ImageSource
281281
* in its own specific thread. Pool and TBB multi-threaders maintain
282282
* a pool of threads (normally equal to number of processing cores)
283283
* which they use to process the pieces. This normally results
284-
* in a single thread being reused to process multiple pieces.
284+
* in a single thread being reused to process multiple work units.
285285
*
286286
* \sa GenerateData(), SplitRequestedRegion() */
287287
virtual void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,

Modules/Core/Common/include/itkImageSource.hxx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ ImageSource<TOutputImage>
212212
const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter();
213213
const unsigned int validThreads = splitter->GetNumberOfSplits(outputPtr->GetRequestedRegion(), this->GetNumberOfWorkUnits());
214214

215-
this->GetMultiThreader()->SetNumberOfThreads(validThreads);
215+
this->GetMultiThreader()->SetNumberOfWorkUnits(validThreads);
216216
this->GetMultiThreader()->SetSingleMethod(callbackFunction, &str);
217217

218218
this->GetMultiThreader()->SingleMethodExecute();
@@ -238,7 +238,7 @@ ImageSource< TOutputImage >
238238
}
239239
else
240240
{
241-
this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfWorkUnits());
241+
this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
242242
this->GetMultiThreader()->template ParallelizeImageRegion<OutputImageDimension>(
243243
this->GetOutput()->GetRequestedRegion(),
244244
[this](const OutputImageRegionType & outputRegionForThread)
@@ -287,10 +287,10 @@ ITK_THREAD_RETURN_TYPE
287287
ImageSource< TOutputImage >
288288
::ThreaderCallback(void *arg)
289289
{
290-
using ThreadInfo = MultiThreaderBase::ThreadInfoStruct;
290+
using ThreadInfo = MultiThreaderBase::WorkUnitInfo;
291291
ThreadInfo * threadInfo = static_cast<ThreadInfo *>(arg);
292-
ThreadIdType threadId = threadInfo->ThreadID;
293-
ThreadIdType threadCount = threadInfo->NumberOfThreads;
292+
ThreadIdType threadId = threadInfo->WorkUnitID;
293+
ThreadIdType threadCount = threadInfo->NumberOfWorkUnits;
294294
ThreadStruct *str = (ThreadStruct *)(threadInfo->UserData);
295295

296296
// execute the actual method with appropriate output region

Modules/Core/Common/include/itkImageToImageFilter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace itk
4848
* GenerateData(), the image processing will run in a single thread and the
4949
* implementation is responsible for allocating its output data. If a filter
5050
* provides an implementation of ThreadedGenerateData() instead, the image
51-
* will be divided into a number of pieces, a number of threads will be
51+
* will be divided into a number of work units, a number of threads will be
5252
* spawned, and ThreadedGenerateData() will be called in each thread. Here,
5353
* the output memory will be allocated by this superclass prior to calling
5454
* ThreadedGenerateData().

Modules/Core/Common/include/itkImageTransformer.hxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ ImageTransformer< TInputImage >
278278
ThreadStruct str;
279279
str.Filter = this;
280280

281-
this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfWorkUnits());
281+
this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
282282
this->GetMultiThreader()->SetSingleMethod(callbackFunction, &str);
283283

284284
this->GetMultiThreader()->SingleMethodExecute();
@@ -337,10 +337,10 @@ ImageTransformer< TInputImage >
337337
ThreadStruct *str;
338338
ThreadIdType total, threadId, threadCount;
339339

340-
threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID;
341-
threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads;
340+
threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID;
341+
threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits;
342342

343-
str = (ThreadStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData );
343+
str = (ThreadStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData );
344344

345345
// execute the actual method with appropriate output region
346346
// first find out how many pieces extent can be split into.

Modules/Core/Common/include/itkMultiThreaderBase.h

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object
7575
/** Run-time type information (and related methods). */
7676
itkTypeMacro(MultiThreaderBase, Object);
7777

78-
/** Get/Set the number of threads to create. It will be clamped to the range
78+
/** Get/Set the number of threads to use. It will be clamped to the range
7979
* [ 1, m_GlobalMaximumNumberOfThreads ], so the caller of this method should
8080
* check that the requested number of threads was accepted. */
81-
virtual void SetNumberOfThreads(ThreadIdType numberOfThreads);
82-
itkGetConstMacro(NumberOfThreads, ThreadIdType);
81+
virtual void SetMaximumNumberOfThreads( ThreadIdType numberOfThreads );
82+
itkGetConstMacro( MaximumNumberOfThreads, ThreadIdType );
83+
84+
/** Get/Set the number of work units to create. It might be clamped to the range
85+
* [ 1, SomeMaximumNumber ], so the caller of this method should
86+
* check that the requested number of work units was accepted. */
87+
virtual void SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits );
88+
itkGetConstMacro( NumberOfWorkUnits, ThreadIdType );
8389

8490
/** Set/Get the maximum number of threads to use when multithreading. It
8591
* will be clamped to the range [ 1, ITK_MAX_THREADS ] because several arrays
@@ -149,27 +155,33 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object
149155
/** This is the structure that is passed to the thread that is
150156
* created from the SingleMethodExecute. It is passed in as a void *,
151157
* and it is up to the method to cast correctly and extract the information.
152-
* The ThreadID is a number between 0 and NumberOfThreads-1 that
153-
* indicates the id of this thread. The UserData is the
158+
* The WorkUnitID is a number between 0 and NumberOfWorkUnits-1 that
159+
* indicates the id of this work unit. The UserData is the
154160
* (void *)arg passed into the SetSingleMethod. */
155-
struct ThreadInfoStruct
156-
{
157-
ThreadIdType ThreadID;
158-
ThreadIdType NumberOfThreads;
159-
void* UserData;
161+
struct WorkUnitInfo
162+
{
163+
ThreadIdType WorkUnitID;
164+
ThreadIdType NumberOfWorkUnits;
165+
void* UserData;
160166
ThreadFunctionType ThreadFunction;
161-
enum { SUCCESS, ITK_EXCEPTION, ITK_PROCESS_ABORTED_EXCEPTION, STD_EXCEPTION, UNKNOWN } ThreadExitCode;
162-
};
167+
enum
168+
{
169+
SUCCESS,
170+
ITK_EXCEPTION,
171+
ITK_PROCESS_ABORTED_EXCEPTION,
172+
STD_EXCEPTION,
173+
UNKNOWN
174+
} ThreadExitCode;
175+
};
163176

164177
/** Execute the SingleMethod (as define by SetSingleMethod) using
165-
* m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be
178+
* m_NumberOfWorkUnits threads. As a side effect the m_NumberOfWorkUnits will be
166179
* checked against the current m_GlobalMaximumNumberOfThreads and clamped if
167180
* necessary. */
168181
virtual void SingleMethodExecute() = 0;
169182

170183
/** Set the SingleMethod to f() and the UserData field of the
171-
* ThreadInfoStruct that is passed to it will be data.
172-
* This method (and all the methods passed to SetMultipleMethod)
184+
* WorkUnitInfo that is passed to it will be data. This method
173185
* must be of type itkThreadFunctionType and must take a single argument of
174186
* type void *. */
175187
virtual void SetSingleMethod(ThreadFunctionType, void *data) = 0;
@@ -264,23 +276,25 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object
264276

265277
static ITK_THREAD_RETURN_TYPE ParallelizeImageRegionHelper(void *arg);
266278

279+
/** The number of work units to create. */
280+
ThreadIdType m_NumberOfWorkUnits;
281+
267282
/** The number of threads to use.
268-
* The m_NumberOfThreads must always be less than or equal to
283+
* The m_MaximumNumberOfThreads must always be less than or equal to
269284
* the m_GlobalMaximumNumberOfThreads before it is used during the execution
270-
* of a threaded method. Its value is clamped in the SingleMethodExecute()
271-
* and MultipleMethodExecute(). Its value is initialized to
285+
* of a threaded method. Its value is initialized to
272286
* m_GlobalDefaultNumberOfThreads at construction time. Its value is clamped
273287
* to the current m_GlobalMaximumNumberOfThreads in the
274-
* SingleMethodExecute() and MultipleMethodExecute() methods.
288+
* SingleMethodExecute() method.
275289
*/
276-
ThreadIdType m_NumberOfThreads;
290+
ThreadIdType m_MaximumNumberOfThreads;
277291

278292
/** Static function used as a "proxy callback" by multi-threaders. The
279-
* threading library will call this routine for each thread, which
280-
* will delegate the control to the prescribed SingleMethod. This
281-
* routine acts as an intermediary between the multi-threaders and the
282-
* user supplied callback (SingleMethod) in order to catch any
283-
* exceptions thrown by the threads. */
293+
* threading library will call this routine for each thread, which
294+
* will delegate the control to the prescribed SingleMethod. This
295+
* routine acts as an intermediary between the multi-threaders and the
296+
* user supplied callback (SingleMethod) in order to catch any
297+
* exceptions thrown by the threads. */
284298
static ITK_THREAD_RETURN_TYPE SingleMethodProxy(void *arg);
285299

286300
/** The method to invoke. */
@@ -300,5 +314,5 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object
300314
ITKCommon_EXPORT std::ostream& operator << (std::ostream& os,
301315
const MultiThreaderBase::ThreaderType& threader);
302316

303-
} // end namespace itk
317+
} // end namespace itk
304318
#endif

Modules/Core/Common/include/itkPlatformMultiThreader.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,26 +105,26 @@ It can affect all MultiThreaderBase's derived classes in ITK");
105105
#endif
106106

107107
/** Execute the SingleMethod (as define by SetSingleMethod) using
108-
* m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be
108+
* m_NumberOfWorkUnits threads. As a side effect the m_NumberOfWorkUnits will be
109109
* checked against the current m_GlobalMaximumNumberOfThreads and clamped if
110110
* necessary. */
111111
void SingleMethodExecute() override;
112112

113113
/** Execute the MultipleMethods (as define by calling SetMultipleMethod for
114-
* each of the required m_NumberOfThreads methods) using m_NumberOfThreads
115-
* threads. As a side effect the m_NumberOfThreads will be checked against the
114+
* each of the required m_NumberOfWorkUnits methods) using m_NumberOfWorkUnits
115+
* threads. As a side effect the m_NumberOfWorkUnits will be checked against the
116116
* current m_GlobalMaximumNumberOfThreads and clamped if necessary. */
117117
itkLegacyMacro(void MultipleMethodExecute());
118118

119119
/** Set the SingleMethod to f() and the UserData field of the
120-
* ThreadInfoStruct that is passed to it will be data.
120+
* WorkUnitInfo that is passed to it will be data.
121121
* This method (and all the methods passed to SetMultipleMethod)
122122
* must be of type itkThreadFunctionType and must take a single argument of
123123
* type void *. */
124124
void SetSingleMethod(ThreadFunctionType, void *data) override;
125125

126126
/** Set the MultipleMethod at the given index to f() and the UserData
127-
* field of the ThreadInfoStruct that is passed to it will be data. */
127+
* field of the WorkUnitInfo that is passed to it will be data. */
128128
itkLegacyMacro(void SetMultipleMethod(ThreadIdType index, ThreadFunctionType, void *data));
129129

130130
/** Create a new thread for the given function. Return a thread id
@@ -137,7 +137,10 @@ It can affect all MultiThreaderBase's derived classes in ITK");
137137
* Deprecated. Use C++11 thread support instead. */
138138
itkLegacyMacro(void TerminateThread(ThreadIdType thread_id));
139139

140-
struct ThreadInfoStruct: MultiThreaderBase::ThreadInfoStruct
140+
virtual void SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ) override;
141+
virtual void SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits ) override;
142+
143+
struct WorkUnitInfo: MultiThreaderBase::WorkUnitInfo
141144
{
142145
int *ActiveFlag;
143146
MutexLock::Pointer ActiveFlagLock;
@@ -152,14 +155,14 @@ It can affect all MultiThreaderBase's derived classes in ITK");
152155
/** An array of thread info containing a thread id
153156
* (0, 1, 2, .. ITK_MAX_THREADS-1), the thread count, and a pointer
154157
* to void so that user data can be passed to each thread. */
155-
ThreadInfoStruct m_ThreadInfoArray[ITK_MAX_THREADS];
158+
WorkUnitInfo m_ThreadInfoArray[ITK_MAX_THREADS];
156159

157160
/** Storage of MutexFunctions and ints used to control spawned
158161
* threads and the spawned thread ids. */
159162
int m_SpawnedThreadActiveFlag[ITK_MAX_THREADS];
160163
MutexLock::Pointer m_SpawnedThreadActiveFlagLock[ITK_MAX_THREADS];
161164
ThreadProcessIdType m_SpawnedThreadProcessID[ITK_MAX_THREADS];
162-
ThreadInfoStruct m_SpawnedThreadInfoArray[ITK_MAX_THREADS];
165+
WorkUnitInfo m_SpawnedThreadInfoArray[ITK_MAX_THREADS];
163166

164167
#if !defined ( ITK_LEGACY_REMOVE )
165168
/** The methods to invoke. */
@@ -170,7 +173,7 @@ It can affect all MultiThreaderBase's derived classes in ITK");
170173
#endif
171174

172175
/** spawn a new thread for the SingleMethod */
173-
ThreadProcessIdType SpawnDispatchSingleMethodThread(ThreadInfoStruct *);
176+
ThreadProcessIdType SpawnDispatchSingleMethodThread(WorkUnitInfo *);
174177
/** wait for a thread in the threadpool to finish work */
175178
void SpawnWaitForSingleMethodThread(ThreadProcessIdType);
176179

0 commit comments

Comments
 (0)