Jump to content
  • Advertisement
Sign in to follow this  
Alundra

InterlockedExchangeAdd preferred to InterlockedExchangeSubtract

This topic is 510 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,
I often see InterlockedExchangeAdd used instead of InterlockedExchangeSubtract, so basically doing :

InterlockedExchangeAdd( &Variable, -Value );

I looked on MSDN and searched on google but I don't see why it's preferred.
Any idea ?

Edited by Alundra

Share this post


Link to post
Share on other sites
Advertisement

InterlockedExchangeSubtract is actually a utility function using InterlockedExchangeAdd.

It only has been added a couple of years ago so untill then, you simply had to pass the negative value.

Share this post


Link to post
Share on other sites

The add variant is a compiler intrinsic.

That means the compiler doesn't need to use a function call, it can replace it directly with the correct CPU opcodes. That's also why it has additional rules about alignment that the subtract version does not.

The subtract version is a full-fledged function call. It incurs the cost of a function call and the cost of loading the values into registers when called, restoring from the registers when done, etc. That's overhead in addition to the instructions being run.

The overhead for the function call is extremely small, typically single-digit nanoseconds, and programmers typically have no qualms about the cost of a function call. Games have millions of function calls every second.  But if you have a choice between something with a cost and something without a cost, it is generally better to get the no-cost version.

Share this post


Link to post
Share on other sites

Ok, that gives a good explanation.
I see only version of atomic for long and long long, meaning int32 and int64, is it not possible to do atomic operation on unsigned ?

Share this post


Link to post
Share on other sites
The standard operating procedure I've seen used for years is to just reinterpret_cast<LONG *>(&someUnsigned) and be done with it :-)

Share this post


Link to post
Share on other sites

Ok, it's basically what I ended as solution too like that (volatile needed) :

reinterpret_cast< volatile long* >( &Variable )

But then how work the subtract for the unsigned value because if you do :

InterlockedExchangeAdd( reinterpret_cast< volatile long* >( &Variable ), -Value );

For a int32, surely issues never happen because the range will always be valid, but is it safe for an unsigned as well ?

Edited by Alundra

Share this post


Link to post
Share on other sites
IIRC unsigned underflow is well-defined by both C and C++, so as long as you know what the behavior is defined to be, you should be OK.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!