290 likes | 581 Views
ITK Workshop . Multi-Threading. October 5-8, 2005. ITK Workshop – Multi-Threading. Multi-Threading The portable Multi-Threader Mutual Exclusion ThreadedGenerateData BeforeThreadedGenerateData AfterThreadedGenerateData SetNumberOfThreads The Evil legacy of FORTRAN.
E N D
ITK Workshop Multi-Threading October 5-8, 2005
ITK Workshop – Multi-Threading • Multi-Threading • The portable Multi-Threader • Mutual Exclusion • ThreadedGenerateData • BeforeThreadedGenerateData • AfterThreadedGenerateData • SetNumberOfThreads • The Evil legacy of FORTRAN
Insight Toolkit - Advanced Course The Concept of Multi-Tasking
The Multi-Tasking Concept Task A Task B Task C Processor The Operating System assigns processor time to each task
Insight Toolkit - Advanced Course Tasks have independent memory spaces They cannot communicate with each other unless they use sockets or files
Insight Toolkit - Advanced Course The Concept of Multi-Threading
The Multi-Threading Concept Task A T2 Processor T1 T0 A Threading library creates threads and assigns processor time to each thread
Insight Toolkit - Advanced Course Threads from a common Task have the same memory space (Shared Memory) They can simultaneously access variables that were instantiated before creating the threads.
The Multi-Threading in Multi-Processors Task A T2 Processor 1 T1 T0 Processor 2 Processor 3 Processor 4
Insight Toolkit – Multi-Threading Libraries Different Threading libraries are available in different platforms • PThreads • SProc • Win32 Threads
Insight Toolkit – Multi-Threading Libraries ITK Provides a class for hiding the differences between threading libraries itk::MultiThreader Win32Threads PThreads SProc
Insight Toolkit - Advanced Course Using the itk::MultiThreader • Declare a Callback • Instantiate an itk::MultiThreader • Set the number of Threads • Set the callback • Invoke SingleMethodExecute()
Using the Multi-Threader #include “itkMultiThreader.h” int main(int argc, char * argv[]){ typedef itk::MultiThreader ThreaderType; ThreaderType::Pointer threader = ThreaderType::New(); const unsigned int numberOfThreads = atoi( argv[1] ); threader->SetNumberOfThreads( numberOfThreads ); threader->SetSingleMethod( ThreaderCallback,NULL ); threader->SingleMethodExecute(); }
Defining the Theader Callback #include “itkMultiThreader.h” ITK_THREAD_RETURN_TYPE ThreaderCallback( void * arg ) { typedef itk::MultiThreader::ThreadInfoStruct ThreadInfoType; ThreadInfoType *infoStruct =static_cast< ThreadInfoType * >( arg ); const unsigned int threadId = infoStruct->ThreadID; std::cout << “Thread = “ << threadId << std::endl; ITK_THREAD_RETURN_TYPE value; return value; }
Insight Toolkit - Advanced Course Exercise 31a Run the Multi-Caster for different numbers of Threads
Insight Toolkit - Advanced Course DON’T PUSH THIS BUTTON !
Insight Toolkit - Advanced Course DON’T TRY TO WRITE TO SHARED DATA FROM MULTIPLE THREADS
Insight Toolkit - Advanced Course Exercise 31b Do the wrong thing on purpose: Attempt to write to a static variable simultaneously from different Threads
Defining the WRONG Theader Callback #include “itkMultiThreader.h” static unsigned long intCounter= 0; ITK_THREAD_RETURN_TYPE ThreaderCallback( void * arg ) { typedef itk::MultiThreader::ThreadInfoStruct ThreadInfoType; ThreadInfoType *infoStruct =static_cast< ThreadInfoType * >( arg );const unsigned int threadId = infoStruct->ThreadID; Counter++; std::cout << “Thread = “ << threadId;std::cout << “Counter = “ <<Counter<< std::endl; ITK_THREAD_RETURN_TYPE value; return value; }
Insight Toolkit - Advanced Course IF YOU REALLY REALLY WANT TO PUSH THIS BUTTON
Insight Toolkit - Advanced Course Exercise 31c Prevent the possible simultaneous access to share memory by introducion Mutual Exclusion
Defining the RIGHT Theader Callback #include “itkMultiThreader.h” #include “itkSimpleFastMutexLock.h” static unsigned long intCounter= 0; static itk::SimpleFastMutexLockmutex; ITK_THREAD_RETURN_TYPE ThreaderCallback( void * arg ) { mutex.Lock(); Counter++; mutex.UnLock(); std::cout << “Counter = “ << Counter << std::endl; ITK_THREAD_RETURN_TYPE value; return value; }
Insight Toolkit - Advanced Course Exercise 31d Use the itk::RealTimeClock to measure how fast (or how slow) the Mutual exclusion
Timing the Mutual Exclusion Class #include “itkSimpleFastMutexLock.h” #include “itkRealTimeClock.h” static unsigned long intCounter= 0; static itk::SimpleFastMutexLockmutex; int main() { const unsigned int N = 400000L; itk::RealTimeClock clock; const double T1 = clock.GetTimestamp(); for(unsigned long i=0; i < N; i++) { mutex.Lock(); Counter++; mutex.UnLock(); } const double TT = clock.GetTimestamp() – T1; std::cout << “Time = “ << TT / N << td::endl; ITK_THREAD_RETURN_TYPE value; return value; }
Insight Toolkit - Advanced Course Writing a Multi-Threading Filter
Insight Toolkit – Filters Hierarchy itk::ProcessObject public: MultiThreader * GetThreader(); private: MultiThreader m_Threader int m_NumberOfThreads
Insight Toolkit – Filters Hierarchy itk::ImageSource public: virtual voidBeforeThreadedGenerateData();virtual voidAfterThreadedGenerateData(); virtual voidThreadedGenerateData( const OutputImageRegionType & region,intthreadId );
Insight Toolkit – GenerateData() BeforeThreadedGenerateData TGD TGD TGD TGD TGD AfterThreadedGenerateData