G
Guest
I have the following two code blocks which should only have 3 threads at the
most calling the function and collisions are very unlikely because all 3
threads should rarely be calling this function at the *exact* same time. I
am wondering which code block I should use for optimum efficiency and speed
given the conditions. I've hear that the Interlocked class is much more
efficient than a Mutex and should be used when it makes sense to, however I
don't know if this is true for sure. I've heard that the Mutex will cause
(or is it *may* cause) a context switch and that the Interlocked class does
not. Which code block will be fastest and why?
Thanks,
// **** Code block 1*****
bool sendMsgToIFac = false;
do
{
int lastSeqNum = this.lastSeqNumReceived;
int newSeqNum;
if(
(seqNum != (lastSeqNum + 1))
&& !(seqNum == 0 && (lastSeqNum == (this.maxSeqNums - 1)))
)
{
// Ignore message, unexpected seq num
newSeqNum = lastSeqNum;
sendMsgToIFac = false;
}
else
{
newSeqNum = lastSeqNum + 1;
if(newSeqNum > this.maxSeqNums - 1)
newSeqNum = 0;
sendMsgToIFac = true;
}
} while(lastSeqNum != Interlocked.CompareExchange(ref lastSeqNumReceived,
newSeqNum, lastSeqNum));
//**** OR ******* Code block 2
bool sendMsgToIFac = false;
this.receiveSeqNumMutex.WaitOne();
if(
(seqNum != (this.lastSeqNumReceived + 1))
&& !(seqNum == 0 && (this.lastSeqNumReceived == (this.maxSeqNums - 1)))
)
{
// Ignore message, unexpected seq num
sendMsgToIFac = false;
}
else
{
this.lastSeqNumReceived++;
if(this.lastSeqNumReceived > this.maxSeqNums - 1)
this.lastSeqNumReceived = 0;
sendMsgToIFac = true;
}
this.receiveSeqNumMutex.ReleaseMutex();
Also, from the following article:
http://msdn.microsoft.com/library/d...enref/html/cpconThreadingDesignGuidelines.asp
"
Be aware of issues with the lock statement (SyncLock in Visual Basic). It is
tempting to use the lock statement to solve all threading problems. However,
the System.Threading.Interlocked Class is superior for updates that must be
atomic. It executes a single lock prefix if there is no contention. In a code
review, you should watch out for instances like the one shown in the
following example.
[Visual Basic]
SyncLock Me
myField += 1
End SyncLock
[C#]
lock(this)
{
myField++;
}
If you replace the previous example with the following one, you will improve
performance.
[Visual Basic]
System.Threading.Interlocked.Increment(myField)
[C#]
System.Threading.Interlocked.Increment(myField);
"
Why is the Interlocked version more efficient than the lock version?
Thanks,
most calling the function and collisions are very unlikely because all 3
threads should rarely be calling this function at the *exact* same time. I
am wondering which code block I should use for optimum efficiency and speed
given the conditions. I've hear that the Interlocked class is much more
efficient than a Mutex and should be used when it makes sense to, however I
don't know if this is true for sure. I've heard that the Mutex will cause
(or is it *may* cause) a context switch and that the Interlocked class does
not. Which code block will be fastest and why?
Thanks,
// **** Code block 1*****
bool sendMsgToIFac = false;
do
{
int lastSeqNum = this.lastSeqNumReceived;
int newSeqNum;
if(
(seqNum != (lastSeqNum + 1))
&& !(seqNum == 0 && (lastSeqNum == (this.maxSeqNums - 1)))
)
{
// Ignore message, unexpected seq num
newSeqNum = lastSeqNum;
sendMsgToIFac = false;
}
else
{
newSeqNum = lastSeqNum + 1;
if(newSeqNum > this.maxSeqNums - 1)
newSeqNum = 0;
sendMsgToIFac = true;
}
} while(lastSeqNum != Interlocked.CompareExchange(ref lastSeqNumReceived,
newSeqNum, lastSeqNum));
//**** OR ******* Code block 2
bool sendMsgToIFac = false;
this.receiveSeqNumMutex.WaitOne();
if(
(seqNum != (this.lastSeqNumReceived + 1))
&& !(seqNum == 0 && (this.lastSeqNumReceived == (this.maxSeqNums - 1)))
)
{
// Ignore message, unexpected seq num
sendMsgToIFac = false;
}
else
{
this.lastSeqNumReceived++;
if(this.lastSeqNumReceived > this.maxSeqNums - 1)
this.lastSeqNumReceived = 0;
sendMsgToIFac = true;
}
this.receiveSeqNumMutex.ReleaseMutex();
Also, from the following article:
http://msdn.microsoft.com/library/d...enref/html/cpconThreadingDesignGuidelines.asp
"
Be aware of issues with the lock statement (SyncLock in Visual Basic). It is
tempting to use the lock statement to solve all threading problems. However,
the System.Threading.Interlocked Class is superior for updates that must be
atomic. It executes a single lock prefix if there is no contention. In a code
review, you should watch out for instances like the one shown in the
following example.
[Visual Basic]
SyncLock Me
myField += 1
End SyncLock
[C#]
lock(this)
{
myField++;
}
If you replace the previous example with the following one, you will improve
performance.
[Visual Basic]
System.Threading.Interlocked.Increment(myField)
[C#]
System.Threading.Interlocked.Increment(myField);
"
Why is the Interlocked version more efficient than the lock version?
Thanks,