Thread: Double-Checked Locking pattern issue

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    Double-Checked Locking pattern issue

    Hello gurus,


    For the wellknown Double-Checked Locking pattern,

    http://www.ddj.com/184405726?pgno=1

    Step 1: Allocate memory to hold a Singleton object.
    Step 2: Construct a Singleton object in the allocated memory.
    Step 3: Make pInstance point to the allocated memory.

    After reading for a couple of times, I still do not understand why some compiler will exchange step 2 and step 3 code? If there are any exception in step 2, the swap code will make pInstance point to an invalid memory address. Any ideas why compiler do the swap?

    Code:
    Singleton* Singleton::instance() {
    if (pInstance == 0) {
    Lock lock;
    if (pInstance == 0) {
    pInstance = // Step 3
    operator new(sizeof(Singleton)); // Step 1
    new (pInstance) Singleton; // Step 2
    }
    }
    return pInstance;
    }

    thanks in advance,
    George

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You have to remember that, in machine instructions, a function like operator new might simply push its return value into a register, and the caller will access it from that register.

    So the sequence (as far as the machine is concerned);

    Step 1: operator new is called, allocates memory, and leaves the address in some_register
    Step 2: placement new is invoked ("operator new(sizeof(Singleton));" by accessing the address directly from some_register
    Step 3: the value from some_register is copied into the variable pInstance.

    If operations on registers are significantly more efficient (i.e. faster) than operations on other areas of memory, then this sequence of events may be much more efficient than alternatives.

    Practically, there are many other ways of doing things (eg instruction pipelining, instruction cacheing, etc etc) so a CPU can do things internally in a different order but still achieve the same net effect that the programmer expects of the code. One of the joys of writing an optimising compiler is working out what reordering of events yields the "optimal" performance, without changing the testable net behaviour (other than performance) that a human running the code would expect.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi grumpy,


    Thanks for reply. I am confused about your points. My question is reorder step 2 and step 3 will improve performance, but why?

    Your reply below does not reorder step 2 and step 3? Please feel free to correct me if I am wrong to understand your points.

    Quote Originally Posted by grumpy View Post
    You have to remember that, in machine instructions, a function like operator new might simply push its return value into a register, and the caller will access it from that register.

    So the sequence (as far as the machine is concerned);

    Step 1: operator new is called, allocates memory, and leaves the address in some_register
    Step 2: placement new is invoked ("operator new(sizeof(Singleton));" by accessing the address directly from some_register
    Step 3: the value from some_register is copied into the variable pInstance.

    If operations on registers are significantly more efficient (i.e. faster) than operations on other areas of memory, then this sequence of events may be much more efficient than alternatives.

    Practically, there are many other ways of doing things (eg instruction pipelining, instruction cacheing, etc etc) so a CPU can do things internally in a different order but still achieve the same net effect that the programmer expects of the code. One of the joys of writing an optimising compiler is working out what reordering of events yields the "optimal" performance, without changing the testable net behaviour (other than performance) that a human running the code would expect.

    regards,
    George

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    In the sequence I described, the second two steps can be interchanged, and the net effect is the same (raw memory is allocated, an object is constructed from that raw memory, and the address is stored in a particular pointer unless the process is short-circuited because an exception is thrown).

    Doing such things in different orders can allow use of different machine instructions, registers, etc. And some of those ways are, on particular machines, more efficient than others despite achieving the same observable effect.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. re-entrancy pattern issue setbacks
    By George2 in forum Windows Programming
    Replies: 0
    Last Post: 04-12-2008, 02:23 AM
  2. functions and passing data
    By redmondtab in forum C Programming
    Replies: 41
    Last Post: 09-21-2006, 12:04 PM
  3. Rectangular Approximation Program Help
    By Noah in forum C Programming
    Replies: 4
    Last Post: 03-15-2006, 02:23 PM
  4. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM
  5. Rounding issue with double
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 05-08-2002, 08:11 PM