[Insight-developers] RE: multi-thread filter
Miller, James V (CRD)
millerjv@crd.ge.com
Tue, 25 Sep 2001 12:22:33 -0400
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_001_01C145DE.480751A0
Content-Type: text/plain;
charset="iso-8859-1"
Lydia had an issue with multithreading some of her filters. She needed to perform some filter
initialization prior to having the threads spawned. Here original message is below.
To address this, I modified the pipeline execution model so that the default implementation of
GenerateData() inherited from ImageSource performs the following steps:
1) Allocate the output buffer
2) Call BeforeThreadedGenerateData()
3) Spawn threads, calling ThreadedGenerateData() in each thread.
4) Call AfterThreadedGenerateData()
This added two new methods: ImageSource::BeforeThreadedGenerateData() and
ImageSource::AfterThreadedGenerateData(). These methods are called in the main processing thread
before/after the threaded computation is performed. You can use these methods to perform setup or
breakdown operations. A setup operation might initialize member ivars so that they are ready for all
the threads to use (be careful that their use by each thread is done in a thread safe manner). A
breakdown operation might merge or summarize information calculated by threads.
These methods are a convenience operation and do not have to be used. They only apply to the
ThreadedGenerateData() case. There is no corresponding BeforeGenerateData(), AfterGenerateData()
pair since those operations could simply be put in the GenerateData() method of a single threaded
filter.
There is another way this could have been done (and can still be done) which is to use a MutexLock
inside the ThreadedGenerateData() method to synchronize the threads. You would use a mutex lock
around the initialization code. The first thread to get inside the lock would perform all the
initialization and then set an ivar to indicate that everything was initialized. Then it would
release the lock. The other threads would each grab the lock, see that everything was initialized
and release the lock.
The filter would have an ivar of type SimpleFastMutexLock m_Lock and an ivar m_Initialized. The
ThreadedGenerateData() method would then have code that looks like
m_Lock.Lock();
if (!m_Initialized)
{
// perform initialization for all the threads
// set flag so other threads will not initialize
m_Initialized = true;
}
m_Lock.UnLock();
The tricky part here is resetting m_Initialized after the filter finishes executing. But you could
use a similar locking mechanism.
This methodology can still be used but it does complicate the ThreadedGenerateData() methods. The
BeforeThreadedGenerateData()/AfterThreadedGenerateData() methods should allow you to do most of the
same operations but without the complexity of setting up and releasing mutex locks.
-----Original Message-----
From: Lydia Ng [ mailto:lng@insightful.com <mailto:lng@insightful.com> ]
Sent: Monday, September 24, 2001 11:21 PM
To: Miller, James V (CRD)
Subject: multi-thread filter
Hi Jim,
Wonder if I could bounce an idea at you?
In our multi-threading filter implementation, I see
the need for initializing function (evoked before
ImageSource::GenerateData() ) which allows one to set
the state of a filter which otherwise can not be done
in a thread safe manner.
For example, the interpolation function caches some
information about the input image buffer size during
SetInputImage().
So I can't connect the input image to the interpolator
until the buffer size is valid.
In a single-threaded situation I would connect
the function at the beginning of GenerateData()
Since SetInputImage() is not thread-safe it
would be risky to do it in ThreadedGenerateData().
Besides if I wanted to use the same interpolator function
for all the threads (which is okay since Evaluate() is
thread-safe), evoking SetInputImage() in ThreadedGenerateData()
would be highly redundant.
Any thoughts on the idea of some Initialize method for
multi-threaded filters?
Thanks,
Lydia
------_=_NextPart_001_01C145DE.480751A0
Content-Type: text/html;
charset="iso-8859-1"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE></TITLE>
<META content="MSHTML 5.50.4616.200" name=GENERATOR></HEAD>
<BODY>
<P><FONT size=2>Lydia had an issue with multithreading some of her
filters. She needed to perform some filter initialization prior to having
the threads spawned. Here original message is below.</FONT></P>
<P><FONT size=2>To address this, I modified the pipeline execution model so that
the default implementation of GenerateData() inherited from ImageSource performs
the following steps:</FONT></P>
<P><FONT color=#0000ff size=2>1) Allocate the output buffer<BR>2) Call
BeforeThreadedGenerateData()<BR>3) Spawn threads, calling ThreadedGenerateData()
in each thread.<BR>4) Call AfterThreadedGenerateData()</FONT></P>
<P><FONT color=#0000ff size=2>This added two new methods:
ImageSource::BeforeThreadedGenerateData() and
ImageSource::AfterThreadedGenerateData(). These methods are called in the
main processing thread before/after the threaded computation is performed.
You can use these methods to perform setup or breakdown operations. A setup
operation might initialize member ivars so that they are ready for all the
threads to use (be careful that their use by each thread is done in a thread
safe manner). A breakdown operation might merge or summarize information
calculated by threads.</FONT></P>
<DIV><FONT color=#0000ff size=2>These methods are a convenience operation and do
not have to be used. They only apply to the ThreadedGenerateData()
case. There is no corresponding BeforeGenerateData(), AfterGenerateData()
pair since those operations could simply be put in the GenerateData() method of
a single threaded filter.</DIV>
<P>There is another way this could have been done (and can still be done) which
is to use a MutexLock inside the ThreadedGenerateData() method to synchronize
the threads. </FONT><FONT size=2>You would use a mutex lock around the
initialization code. The first thread to get inside the lock would perform
all the initialization and then set an ivar to indicate that everything was
initialized. Then it would release the lock. The other threads would
each grab the lock, see that everything was initialized and release the
lock.<BR><BR>The filter would have an ivar of type SimpleFastMutexLock m_Lock
and an ivar m_Initialized. The ThreadedGenerateData() method would then have
code that looks like<BR><BR>m_Lock.Lock();<BR>if (!m_Initialized)<BR>
{<BR> // perform initialization for all the threads<BR> <BR> //
set flag so other threads will not initialize<BR> m_Initialized =
true;<BR> }<BR>m_Lock.UnLock();<BR><BR>The tricky part here is resetting
m_Initialized after the filter finishes executing. But you could use a
similar locking mechanism.</FONT></P>
<DIV><FONT size=2><FONT color=#0000ff>This methodology can still be used but it
does complicate the ThreadedGenerateData() methods. The
BeforeThreadedGenerateData()/AfterThreadedGenerateData() methods should allow
you to do most of the same operations but without the complexity of setting up
and releasing mutex locks.</FONT></DIV>
<P><BR><BR></FONT><FONT size=2><BR>-----Original Message-----<BR>From: Lydia Ng
[<A href="mailto:lng@insightful.com">mailto:lng@insightful.com</A>]<BR>Sent:
Monday, September 24, 2001 11:21 PM<BR>To: Miller, James V (CRD)<BR>Subject:
multi-thread filter<BR><BR><BR>Hi Jim,<BR><BR>Wonder if I could bounce an idea
at you?<BR><BR>In our multi-threading filter implementation, I see<BR>the need
for initializing function (evoked before<BR>ImageSource::GenerateData() ) which
allows one to set<BR>the state of a filter which otherwise can not be done<BR>in
a thread safe manner.<BR><BR>For example, the interpolation function caches
some<BR>information about the input image buffer size
during<BR>SetInputImage().<BR><BR>So I can't connect the input image to the
interpolator<BR>until the buffer size is valid.<BR><BR>In a single-threaded
situation I would connect<BR>the function at the beginning of
GenerateData()<BR><BR>Since SetInputImage() is not thread-safe it<BR>would be
risky to do it in ThreadedGenerateData().<BR><BR>Besides if I wanted to use the
same interpolator function<BR>for all the threads (which is okay since
Evaluate() is<BR>thread-safe), evoking SetInputImage() in
ThreadedGenerateData()<BR>would be highly redundant.<BR><BR>Any thoughts on the
idea of some Initialize method for<BR>multi-threaded
filters?<BR><BR>Thanks,<BR>Lydia<BR><BR><BR><BR><BR></P></FONT></BODY></HTML>
------_=_NextPart_001_01C145DE.480751A0--