views:

512

answers:

2

Microsoft offers the InterlockedCompareExchange function for performing atomic compare-and-swap operations. There is also an _InterlockedCompareExchange intrinsic.

On x86 these are implemented using the cmpxchg instruction.

However, reading through the documentation on these three approaches, they don't seem to agree on the alignment requirements.

Intel's reference manual says nothing about alignment (other than that if alignment checking is enabled and an unaligned memory reference is made, an exception is generated)

I also looked up the lock prefix, which specifically states that

The integrity of the LOCK prefix is not affected by the alignment of the memory field.

(emphasis mine)

So Intel seems to say that alignment is irrelevant. The operation will be atomic no matter what.

The _InterlockedCompareExchange intrinsic documentation also says nothing about alignment, however the InterlockedCompareExchange function states that

The parameters for this function must be aligned on a 32-bit boundary; otherwise, the function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems.

So what gives? Are the alignment requirements for InterlockedCompareExchange just to make sure the function will work even on pre-486 CPU's where the cmpxchg instruction isn't available? That seems likely based on the above information, but I'd like to be sure before I rely on it. :)

Or is alignment required by the ISA to guarantee atomicity, and I'm just looking the wrong places in Intel's reference manuals?

+3  A: 

See this SO question: natural alignment is important for performance, and is required on the x64 architecture (so it's not just PRE-x86 systems, but POST-x86 ones too -- x64 may still be a bit of a niche case but it's growing in popularity after all;-); that may be why Microsoft documents it as required (hard to find docs on whether MS has decided to FORCE the alignment issue by enabling alignment checking -- that may vary by Windows version; by claiming in the docs that alignment is required, MS keeps the freedom to force it in some version of Windows even if they did not force it on others).

Alex Martelli
Thanks. And bah, of course someone else had asked this before. I shouldn't be surprised... :pAbout x64, does it require alignment for *all* atomic instructions, even the ones that didn't require it in 32-bit mode? Not that I don't believe you, but it seems a bit surprising if they're breaking backwards compatibility like that. Got a source for that?
jalf
I have no info on x64's alignment issues except Microsoft's (see also http://forum.winimage.com/viewtopic.php?t=137 for other discussions and pointers about x64 alignment, beyond atomicity). BTW, what backwards compatibility? x64 is a new architecture (chips that run it also run x86 for old 32-bit code) so there's no "backwards" -- machine code that runs in x64 (rather than x86 legacy mode) has to have been written/compiled/generated specifically for it, not for x86!-)
Alex Martelli
That link seems to say that alignment is only *required* on Itanium, not x64, which is what I'd expect. It obviously still has a (major) impact on performance, but it would be odd if x64 suddenly required alignment for instructions that didn't require it in x86.And never mind the backwards compatibility thing. It was half brainfart, and half irrelevant to the question. ;) (The instruction set is basically the same though, as far as I know. The changes mainly consists in adding new instructions, and adding another optional prefix byte to allow you to specify one of the new registers)
jalf
Yes, but you can control whether mis-alignment causes exceptions on both x64 AND itanium -- the one difference is that it defaults to off on x64, to on in itanium (where the perf hit if you disable the exceptions is HUGE -- 10 times, vs 2/3 times on x64). Looks like win64 doesn't supply an intrinsic to enable exceptions (it does supply one to DISABLE them!-), but you can do it in machine code.
Alex Martelli
A: 

Microsoft's Interlocked APIs also applied to ia64 (while it still existed). There was no lock prefix on ia64, only the cmpxchg.acq and cmpxchg.rel instructions (or fetchadd and other similar beasties), and these all required alignment if I recall correctly.

Peeter Joot
ia86 still exists, and Windows still runs on it, as far as I know. Anyway, my question was specifically about x86. :)
jalf
re: ia64. I'm pretty sure Windows stopped shipping an os for ia64 after intel released their version of amd64 (x86-64), and no vista nor win7 for ia64. Now there is only the x86 and x86-64 versions of the os. As far as I'm concerned that effectively kills ia64 (unless you count HPUX IPF).re: interlocked and x86. It is my recollection that we first started seeing the Interlocked APIs when microsoft released their ia64 version of the platform SDK. If that is accurate, it would likely explain why the Interlocked documentation does not rely on the LOCK prefix semantics of x86.
Peeter Joot