The ‘volitile’ myth

OK, I think I should clarify something about what I said in regards to all of the Microsoft JIT’ed assignments are volatile.   Yes, that is a true statement, but you cannot simply take that out of context and say “Well, then that means that all of my assignments are safe”.  Yes, they will be, but that doesn’t mean that it will operate the way you think it does.  Take for instance the following code snippet:

 

       Char[] cArr = new Char[20];

       public void Func()

       {

              object secondRef = cArr;

              if (secondRef == cArr)

              {

                     if (secondRef == cArr)

                           return;

              }

       }

 

Upon first glance, you might think that, “Well, since my assignments are all volatile, there’s nothing wrong with this code.  The surprise comes in when you look at the JIT’ed IL:

 

        public void Func()

        {

            object secondRef = cArr;

00000000  mov         edx,dword ptr [ecx+4]

00000003  mov         eax,edx

            if (secondRef == cArr)

00000005  cmp         eax,edx

00000007  jne         00000009

00000009  ret    

        }

 

You’ll notice that the code is optimized and stores the first object reference inside a register with the intent of not having to check the memory location subsequent times (this is the optimization).  So now, let’s decorate the array with the volatile keyword.  You immediately notice that the JITer no longer stores any previous addresses of the array inside a register.  Each comparison call will get the array address from memory:

 

        public void Func()

        {

            object secondRef = cArr;

00000000  mov         eax,dword ptr [ecx+4]

            if (secondRef == cArr)

00000003  cmp         eax,dword ptr [ecx+4]

00000006  jne         0000000B

            {

                if( secondRef == cArr )

00000008  cmp         dword ptr [ecx+4],eax

0000000b  ret  

         }

 

 

If you omit the volatile keyword, the second check is simply removed and a register compare is performed with the previously determined address of the array. When you add the volatile keyword the cmd eax,edx becomes cmp eaxdword ptr[ecx+4] which in works like a memory barrier.   So even though Microsoft’s JITer makes every assignment volatile, you HAVE to keep in mind what type of optimizations occur.

Advertisement

About JohnHowell

I am a professional software developer with over 20 years of experience. I currently specialize in Microsoft technologies such as VS, TFS, C#, VB.Net, WCF, WPF, WW, etc.
This entry was posted in Development. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s