473,804 Members | 3,021 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

MemoryBarrier vs volatile vs lock

Hi All,

I'm trying to get my head around synchronization .

Documentation seems to say that creating a volatile field gives a
memorybarrier.

Great! But when I do a little performance testing Thread.MemoryBa rrier is
40 times slower than accessing a volatile int. Also I don't see any
significant difference between the time to increment a volatile int and a
non-volatile int.

Could the difference all be attributable to the overhead of a function call?

When I read documentation on Thread.Volatile Write it says that all other
processors are guaranteed to see your write immediately.

But when I use reflector to decompile VolatileWrite I get:

public static void VolatileWrite(r ef int address, int value)
{
Thread.MemoryBa rrier();
address = value;
}

Now if the MemoryBarrier is before the write couldn't I throw the
MemoryBarrier on processor1 read value (through the cache) on processor 2 and
then write to address on processor 1 now the next read of address on
processor2 gets its "cached" value from before the new write.

(Boy it's as hard to write about this stuff as it is to read).
processor1: Thread.MemoryBa rrier
processor2: read address getting old_value (old_value cached)
processor1: address = new_value
processor2: read address still returning old_value.

VolatileWrite the way it is written seems to guarantee that any write before
it will get to main memory before this write but makes no guarantees about
this write.

Thanks
Sep 9 '05 #1
15 10625
My Results of running following code:

baseline = 00:00:00.031823 5
volatile_int = 00:00:00.032038 4
Memory Barriers = 00:00:01.144961 4
VolatileMethods = 00:00:02.317065 1
locked = 00:00:00.485872 3
Interlocked = 00:00:00.090715 4

Code:

using System;
using System.Collecti ons.Generic;
using System.Text;
using System.Diagnost ics;
using System.Threadin g;

namespace ConsoleApplicat ion1
{
class Program
{
private object _syncobj = new Object();
private int m_a;
private volatile int m_v;

public void Test()
{
Stopwatch sw = new Stopwatch();

m_a = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
m_a++;

Console.WriteLi ne("baseline = " + sw.Elapsed);

sw.Reset();
m_v = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
m_v++;

Console.WriteLi ne("volatile_in t = " + sw.Elapsed);

sw.Reset();
m_v = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
{
// Thread.MemoryBa rrier();
m_v++;
Thread.MemoryBa rrier();
}

Console.WriteLi ne("Memory Barriers = " + sw.Elapsed);

sw.Reset();
m_a = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
Thread.Volatile Write(ref m_a, Thread.Volatile Read(ref m_a)+1);

Console.WriteLi ne("VolatileMet hods = " + sw.Elapsed);

sw.Reset();
m_a = 0;
sw.Start();

for (int i = 0; i < 10000000; ++i)
{
lock(_syncobj)
{
m_a++;
}
}

Console.WriteLi ne("locked = " + sw.Elapsed);

sw.Reset();
m_a = 0;
sw.Start();

for (int i = 0; i < 10000000; ++i)
{
Interlocked.Inc rement(ref m_a);
}

Console.WriteLi ne("Interlocke d = " + sw.Elapsed);

sw.Reset();
}
static void Main(string[] args)
{
Program p = new Program();
p.Test();
}
}
}
Sep 9 '05 #2


"DanGo" wrote:
My Results of running following code:

baseline = 00:00:00.031823 5
volatile_int = 00:00:00.032038 4
Memory Barriers = 00:00:01.144961 4
VolatileMethods = 00:00:02.317065 1
locked = 00:00:00.485872 3
Interlocked = 00:00:00.090715 4


Note that using a lock is considerably faster than using a memorybarrier.

Doesn't a lock imply a memory barrier ( a read barrier at the top and a
write barrier at the bottom) Since the lock is 4-5 times faster than a pair
of memory barriers and twice as fast as a single barrier. We could use lock
in place of calls to MemoryBarrier.

If a volatile field really gives us a barrier it is much faster. In
addition it also gives the compiler hints on how to treat the field.
Sep 9 '05 #3

"DanGo" <Da***@discussi ons.microsoft.c om> wrote in message
news:EB******** *************** ***********@mic rosoft.com...


"DanGo" wrote:
My Results of running following code:

baseline = 00:00:00.031823 5
volatile_int = 00:00:00.032038 4
Memory Barriers = 00:00:01.144961 4
VolatileMethods = 00:00:02.317065 1
locked = 00:00:00.485872 3
Interlocked = 00:00:00.090715 4


Note that using a lock is considerably faster than using a memorybarrier.


Are you using a multiple processor machine? I ran your test on my machine
and got these results:

baseline = 00:00:00.019197 1
volatile_int = 00:00:00.023364 5
Memory Barriers = 00:00:00.967236 9
VolatileMethods = 00:00:01.952810 8
locked = 00:00:01.780008 2
Interlocked = 00:00:00.725799 6

Memory Barrier is considerably faster than using a lock. I don't know the
synchronization structure well, but its possible that lock doesn't actually
use a memory barrier if there is only one processor.
Sep 9 '05 #4
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:

<snip>
Memory Barrier is considerably faster than using a lock. I don't know the
synchronization structure well, but its possible that lock doesn't actually
use a memory barrier if there is only one processor.


It should do - otherwise you can still have problems, if (for instance)
another thread has a variable value cached in a register.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Sep 9 '05 #5

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:

<snip>
Memory Barrier is considerably faster than using a lock. I don't know the
synchronization structure well, but its possible that lock doesn't
actually
use a memory barrier if there is only one processor.


It should do - otherwise you can still have problems, if (for instance)
another thread has a variable value cached in a register.


Good point, perhaps a more limited memory barrier, no processor cache flush,
just a register flush to processor cache?

Thats conjecture mostly, I have no clue how the performance of sync
primatives work, other than his machine does is not the same as what mine
does.
Sep 9 '05 #6
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
It should do - otherwise you can still have problems, if (for instance)
another thread has a variable value cached in a register.
Good point, perhaps a more limited memory barrier, no processor cache flush,
just a register flush to processor cache?


Possibly - but then couldn't MemoryBarrier do the same thing?
Thats conjecture mostly, I have no clue how the performance of sync
primatives work, other than his machine does is not the same as what mine
does.


Right. For the record, here are the results on my single processor
Pentium-M laptop:

baseline = 00:00:00.038889 0
volatile_int = 00:00:00.039399 9
Memory Barriers = 00:00:00.277513 4
VolatileMethods = 00:00:00.635096 6
locked = 00:00:00.351767 6
Interlocked = 00:00:00.173056 9

Interesting to see that your baseline and volatile int are better than
mine, but all the rest of mine are better than yours. Odd.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Sep 9 '05 #7

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
> It should do - otherwise you can still have problems, if (for instance)
> another thread has a variable value cached in a register.


Good point, perhaps a more limited memory barrier, no processor cache
flush,
just a register flush to processor cache?


Possibly - but then couldn't MemoryBarrier do the same thing?


Very possibly, but I have no clue if it does or not. Peformance gets to be a
sticky thing when you scale out in processors.

Thats conjecture mostly, I have no clue how the performance of sync
primatives work, other than his machine does is not the same as what mine
does.


Right. For the record, here are the results on my single processor
Pentium-M laptop:

baseline = 00:00:00.038889 0
volatile_int = 00:00:00.039399 9
Memory Barriers = 00:00:00.277513 4
VolatileMethods = 00:00:00.635096 6
locked = 00:00:00.351767 6
Interlocked = 00:00:00.173056 9

Interesting to see that your baseline and volatile int are better than
mine, but all the rest of mine are better than yours. Odd.


Might be raw speed, might be due to multiple processors, might be because
yours is a laptop and mine not, might be luck. This is a dual 2.2ghz with
hyperthreading enabled.
Sep 9 '05 #8
Here is an updated version of the source:

This version uses baseline as a normalization for the other tests:

class Program
{
private object _syncobj = new Object();
private int m_a;
private volatile int m_v;

public void Test()
{
Stopwatch sw = new Stopwatch();

m_a = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
m_a++;
sw.Stop();
Console.WriteLi ne("baseline = " + ": 1.0");
float baselineNormali zation = sw.ElapsedTicks ;
sw.Reset();
m_v = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
m_v++;

sw.Stop();
Console.WriteLi ne("volatile_in t = " + ": " +
(sw.ElapsedTick s/baselineNormali zation).ToStrin g());

sw.Reset();
m_v = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
{
// Thread.MemoryBa rrier();
m_v++;
Thread.MemoryBa rrier();
}

sw.Stop();
Console.WriteLi ne("Memory Barriers = " + ": " + (sw.ElapsedTick s
/ baselineNormali zation).ToStrin g());

sw.Reset();
m_a = 0;
sw.Start();
for (int i = 0; i < 10000000; ++i)
Thread.Volatile Write(ref m_a, Thread.Volatile Read(ref m_a)+1);

sw.Stop();
Console.WriteLi ne("VolatileMet hods = " + ": " + (sw.ElapsedTick s
/ baselineNormali zation).ToStrin g());

sw.Reset();
m_a = 0;
sw.Start();

for (int i = 0; i < 10000000; ++i)
{
lock(_syncobj)
{
m_a++;
}
}

sw.Stop();
Console.WriteLi ne("locked = " + ": " + (sw.ElapsedTick s /
baselineNormali zation).ToStrin g());

sw.Reset();
m_a = 0;
sw.Start();

for (int i = 0; i < 10000000; ++i)
{
Interlocked.Inc rement(ref m_a);
}

sw.Stop();
Console.WriteLi ne("Interlocke d = " + ": " + (sw.ElapsedTick s /
baselineNormali zation).ToStrin g());

sw.Reset();
}
static void Main(string[] args)
{
Program p = new Program();
p.Test();
}

Sep 10 '05 #9

"DanGo" <Da***@discussi ons.microsoft.c om> wrote in message
news:E5******** *************** ***********@mic rosoft.com...
Here is an updated version of the source:

This version uses baseline as a normalization for the other tests:

Still seeing quite a bit of difference, what did you get?:

baseline = : 1.0
volatile_int = : 1.007561
Memory Barriers = : 53.18861
VolatileMethods = : 105.0428
locked = : 97.86585
Interlocked = : 39.32712
Sep 10 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
389
by: DanGo | last post by:
Hi All, I'm trying to get my head around synchronization. Documentation seems to say that creating a volatile field gives a memorybarrier. Great! But when I do a little performance testing Thread.MemoryBarrier is 40 times slower than accessing a volatile int. Also I don't see any significant difference between the time to increment a volatile int and a
17
5418
by: Ryan Liu | last post by:
Hi, If I have many threads write to a variable(e.g. var++) and another thread read it on an interval base. For those writing thread, I know I need lock, or its value could be lower ( even I think it is mostly not going to happen for ++ operation since it is not something like read a value and wait sometime then write back in multiple threading environment, BTW, is this understanding right?).
3
1430
by: mpaine | last post by:
Hi everyone, I wrote some code and it seems ok to me but since it is going into a high-use production environment, I wanted some peer-review if possible. Basically, I wanted a way to know if an object is being "reset" and only allow one thread to reset it at any one time. This is what I came up with: Private _lockResetSync As Object = New Object() Private _lockResetWaitEvent As ManualResetEvent = New
94
30380
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock Statement (C# Reference) statement to serialize access. " But when is it better to use "volatile" instead of "lock" ?
0
10583
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10337
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10323
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9160
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7622
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5525
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4301
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3822
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2995
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.