Thread: Atomic Operations

  1. #16
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Here's mine:
    Code:
    /*------------------------------------------------------------------------------
    InterlockedRead - Read a "stable" value in an Interlocked fashion. Returns the
                      the true value of the pointer "at the time" this function
                      returns. This is really only useful for "read with full memory
                      barrier" semantics.
    ------------------------------------------------------------------------------*/
    template<typename T>
    T InterlockedRead(T *psrc)
    {
        T val;
        for (;;)
        {
            val = *psrc;
            if ((T)InterlockedCompareExchange((LONG*)psrc, (LONG)val, (LONG)val) 
                    == val)
                break;
        }//if
    
        return val;
    }//InterlockedRead
    Again, avoid it if you can. Simply using a CriticalSection with spin-count is probably just as fast as well.

    K.I.S.S.

    >> ....volatile is needed
    I disagree. Under MSVC you'll be generating an interlocked operation that you might as well do yourself (or not at all if you can avoid it!). Under any other compiler - volatile and multi-threaded access to variables have nothing to do with each other. But let's start another thread if we're going to go at it on this one

    gg

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Thanks for that one, though. I'm going to integrate it into an CAtomicVar class.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Quote Originally Posted by matsp View Post
    Code:
    x = atomic_var;
    is atomic in itself as long as the variable is aligned correctly. It is guaranteed to give you the value either BEFORE or AFTER an InterlockedXxxx operation, not a "half-way through".
    I have to disagree with this - but only as a "blanket statement". It is true that if you're on an x86 arch. and things are properly aligned and these are 32bit values - then you shouldn't get a "half-way through" value. And I'm sure there are other conditions as well in which you won't get a "half-way through" value - the problem is that conditions do exist in which you will get a half-way through value.

    Especially for folks who are just learning MT programming, the rule of thumb should be "all MT access to the same memory location should be properly synchronized, unless all MT access is read-only".

    gg

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Now the question becomes...
    Is it faster to Lock via a critical section once and unlock or do two atomic operations...?
    I believe I'm going to have to try that.

    UPDATE: It's very close, but using a critical section is slightly slower. It can be as slight as about 8 ms or so (1 000 000 loops).
    Generally, two atomic operations are faster.
    And using compiler instricts makes everything even faster!
    Atomic operations are the way to go.
    Last edited by Elysia; 03-26-2008 at 08:55 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Now the question becomes...
    Is it faster to Lock via a critical section once and unlock or do two atomic operations...?
    I believe I'm going to have to try that.
    Certainly faster to do two locked operations. It's a matter of a few bus cycles. A system call may not cause many bus cycles, but hundreds of clock-cycles will certainly be used [in the simplest case where there is no contention around the critical section. ]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    	DWORD dwTick = timeGetTime();
    	Stuff::CAtomicVar<bool> Var;
    	for (int i = 0; i < 1000000; i++)
    	{
    		Var = true;
    		bool bValue = Var;
    		Var = false;
    	}
    	cout << "Took " << timeGetTime() - dwTick << " ms.\n";
    
    	dwTick = timeGetTime();
    	LONG Var2;
    	Stuff::CritSectEx Lock;
    	bool bUnlock;
    	for (int i = 0; i < 1000000; i++)
    	{
    		//Var2 = true;
    		InterlockedExchange(&Var2, true);
    		Lock.Lock(bUnlock);
    		LONG bValue = Var2;
    		Var2 = false;
    		Lock.Unlock(bUnlock);
    	}
    	cout << "Took " << timeGetTime() - dwTick << " ms.\n";
    27 ms vs 48 ms was the best I got.
    The first is atomic and uses intrinsics.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Locking even a CRITICAL_SECTION already takes one InterlockedCompareExchange, and unlocking it requires another memory barrier, which is the main slowdown of atomic operations.

    And spin counts only help on multi-hardware-threaded architectures - in fact, if there aren't multiple hardware threads available, Windows simply ignores the spin count.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Of course, I used a custom critical section for better performance in this example...
    But I'm still getting deadlocks, curses... >_<
    More unsafe code to purge...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> UPDATE: It's very close, but using a critical section is slightly slower.
    Would be interesting to see what happens on a true SMP system, where full memory barriers are much more expensive.

    gg

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You'd still have the memory barriers on entry and exit of the CS. There have to be full barriers there, otherwise the CPU could reorder some instructions to outside of the CS, defeating its purpose.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #26
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Right. I'm referring to the number of membars associated with a particular approach. For example, with a CS you can mutex access to a whole group of variables - as opposed to using interlocked access for each variable independently.
    On systems where membars are very cheap (or no-ops even), the number of membars may not matter. But on other systems, membars are relatively expensive, and may factor in on your synchronization approach.
    Something to keep in mind when doing "lock free" synchronization via interlocked access (which includes volatile access in MSVC v14 and up).

    Personally, I never try to "get fancy" with a synchronization approach, especially for the first go around. To me, doing so is another form "premature optimization".

    gg

  12. #27
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Codeplug View Post
    Personally, I never try to "get fancy" with a synchronization approach, especially for the first go around. To me, doing so is another form "premature optimization".
    True that, but statistics never hurts.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #28
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The more important issue when increasing the number of controlled variables is, is it permitted for another thread to see the situation where some of the variables have been set?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Atomic operations
    By MarkZWEERS in forum C++ Programming
    Replies: 3
    Last Post: 02-07-2009, 05:21 PM
  2. Atomic integers & memcpy()
    By rasta_freak in forum C Programming
    Replies: 11
    Last Post: 08-05-2008, 12:08 PM
  3. doing floating operations using integer operations
    By ammalik in forum C Programming
    Replies: 10
    Last Post: 08-15-2006, 04:30 AM
  4. Matrix and vector operations on computers
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 05-11-2004, 06:36 AM