3 ms·
> Structs are usually 64-bit aligned in x86 though. You need #pragma pack to be no longer 64-bit aligned on modern compilers. Totally false (just try it). > I
by BeeOnRope 7y ago
> Structs are usually 64-bit aligned in x86 though. You need #pragma pack to be no longer 64-bit aligned on modern compilers.
Totally false (just try it).
> I'm pretty sure DEC Alpha can implement C++11's memory model, albeit inefficiently with full-barriers... but it probably would work.
No, they can't (without widening char to 32 bits). The code you have shown modifies the adjacent elements. Anyone that write a nearby byte in the window between the load and the store will have their write silently clobbered.
You can't fix it with barriers. You need a lock or LL/SC loop.
- dragontamer 7y ago> Totally false (just try it). https://pastebin.com/dMxKijm9 https://pastebin.com/dMxKijm9 The "int a" is definitely 32-bit aligned.
- BeeOnRope 7y agoRight! So you agree now that structures are not "usually 64-bit aligned on x86"?
- dragontamer 7y agoWell, 32-bit aligned in this case. But its not 8-bit aligned :-)
- BeeOnRope 7y agoOf course it is not 8-bit aligned! I never said everything was 8-bit aligned, just that your alignment claim was bizarre. ints will always be (at least) 32-bit aligned. The rules are simple [1]: 1-byte primitives (e.g., chars) are 1-byte aligned 2-byte primitives (e.g., shorts) are 2-byte aligned 4-byte primitives (e.g., ints) are 4-byte aligned 8-byte primitives are 8-byte aligned Etc. The rules for structures are also simple: they will have the alignment of their highest alignment member. That makes sense: the language rules (and ABI) are designed to make sure that primitives have (at least) the above alignment, regardless of where they are: putting them into a structure (or array, etc) can't violate that. This is basically common across any modern platform too - not x86 specific, although some details may vary (e.g., size of primitives). There are weird cases too, like on some 32-bit platforms even (some) 64-bit values are only 32-bit aligned, and the whole 80-bit long double thing, etc: but the basic rules hold. --- [1] Here I give some examples of data types that _commonly_ have the given size, but except for char this is not always true (e.g., some platforms have 8 byte ints, and some have 4 byte longs).
- dragontamer 7y ago> You can't fix it with barriers. You need a lock or LL/SC loop. Agreed on this point. > No, they can't (without widening char to 32 bits). The code you have shown modifies the adjacent elements. Anyone that write a nearby byte in the window between the load and the store will have their write silently clobbered. I guess my misunderstanding was that C++11 gave this guarantee. That's pretty cool. I guess I typically expected specific bitwise operators (ex: atomic_and or atomic_or) to be necessary in these cases. But if DEC Alpha is really the only processor in (somewhat) recent memory that doesn't allow 8-bit granularity, then it makes sense to just standardize upon 8-bit granular reads/writes.
- BeeOnRope 7y agoI would be very hard to write correct software involving threads without that guarantee. Most threaded programs are using lots of private data, and imagine if another thread could just randomly stop on your private data while it was trying to do a nearby write? Maybe you could try to formalize the idea of "keep private data away from data on other threads" or something, but this seems very difficult (in practice, private data is private as an emergent property of the whole application, so is not easily identifiable), and you'd have to give up on a lot of things the existing model offers in terms of write-independence.