Sign in to follow this  

InterlockedExchangeAdd preferred to InterlockedExchangeSubtract

Recommended Posts

Posted (edited)

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

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
Posted (edited)

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this