digitalmars.D.learn - Alignment of struct containing SIMD field - GDC
- Cecil Ward (34/34) Feb 28 2017 struct vec_struct {
- Iain Buclaw (20/52) Mar 01 2017 Yeah, it looks like the semantic analysis pass is defeating us
- Johan Engelen (4/14) Mar 01 2017 With explicit align(32), it works:
- Iain Buclaw (6/23) Mar 01 2017 Well obviously, because it adheres to explicit alignment. The
- Cecil Ward (9/34) Mar 01 2017 Thanks for your help Iain. And many thanks btw for all the
- Cecil Ward (11/36) Mar 01 2017 In a dream world where engineers have nothing better to do, it
- Cecil Ward (3/28) Mar 02 2017 Iain, this of course is present in my version of LDC too. (I
- Johan Engelen (7/12) Mar 02 2017 Poke received ;-)
struct vec_struct { alias field this; bool b; int8 field; } In this code when you look at the generated x64 code output by GDC it seems to be doing a nice job, because it has got the offset right for the 256-bit YMM 'field' correct. Does D automatically propagate the alignment restrictions on the field to the allocation of static structs or structs on the stack? In this case: struct vec_struct { bool b2; struct { alias field this; bool b; int8 field; } } it appears that the offset to 'field' is no longer aligned correctly - offset is 40 bytes in GDC. I don't suppose the compiler will use solely unaligned instructions? In any event, I could take the address of field and then pass that to someone expecting to pick up something with guaranteed correct alignment, if I have understood the D docs. Please don't bite. I'm both new to D and I hope I have understood the x86 SIMD instructions' docs. (Very experienced professional asm and C programmer, but v out-of-date.) Noob q: I notice that the GDC opcodes look a bit odd, for example the compiler generates a 256-bit unaligned fetch followed by an aligned binary operation (I think), eg a movdqu followed by a vpaddd r, ymm ptr blah - is the latter aligned-only? Apologies if I have got this wrong, need to read up. Would someone sanity-check me?
Feb 28 2017
On Wednesday, 1 March 2017 at 06:04:32 UTC, Cecil Ward wrote:struct vec_struct { alias field this; bool b; int8 field; } In this code when you look at the generated x64 code output by GDC it seems to be doing a nice job, because it has got the offset right for the 256-bit YMM 'field' correct. Does D automatically propagate the alignment restrictions on the field to the allocation of static structs or structs on the stack? In this case: struct vec_struct { bool b2; struct { alias field this; bool b; int8 field; } } it appears that the offset to 'field' is no longer aligned correctly - offset is 40 bytes in GDC. I don't suppose the compiler will use solely unaligned instructions? In any event, I could take the address of field and then pass that to someone expecting to pick up something with guaranteed correct alignment, if I have understood the D docs.Yeah, it looks like the semantic analysis pass is defeating us here. It's adding the anonymous struct offset to the aligned field, ignoring completely the original alignment. Or... the anonymous struct alignment != largest field alignment, which probably is the more likely scenario. Please raise a bug against DMD. Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);Noob q: I notice that the GDC opcodes look a bit odd, for example the compiler generates a 256-bit unaligned fetch followed by an aligned binary operation (I think), eg a movdqu followed by a vpaddd r, ymm ptr blah - is the latter aligned-only? Apologies if I have got this wrong, need to read up. Would someone sanity-check me?The x86 allows unaligned loads. But if this is referencing the above data structure, you shouldn't be seeing this if the fields were correctly aligned.
Mar 01 2017
On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);With explicit align(32), it works: https://godbolt.org/g/3GjOHW - Johan
Mar 01 2017
On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:Well obviously, because it adheres to explicit alignment. The compiler just has the wrong idea of how default alignment should work. Raised bug here, and I'm raising a PR now also. https://issues.dlang.org/show_bug.cgi?id=17237Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);With explicit align(32), it works: https://godbolt.org/g/3GjOHW - Johan
Mar 01 2017
On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:Thanks for your help Iain. And many thanks btw for all the general good work which is very much appreciated by this particular geriatric asm programmer. I checked the case of XMM alignment, and it's fine. I presume D does not yet support 512-bit zmm vector objects? (I have seen GDC doing a nice job generating auto-vectorised AVX512 code though - thanks.) The same bug would presumably bite again in that case otherwise?On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:Well obviously, because it adheres to explicit alignment. The compiler just has the wrong idea of how default alignment should work. Raised bug here, and I'm raising a PR now also. https://issues.dlang.org/show_bug.cgi?id=17237Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);With explicit align(32), it works: https://godbolt.org/g/3GjOHW - Johan
Mar 01 2017
On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:In a dream world where engineers have nothing better to do, it would of course be better to effectively delete the inner anonymous struct so that the two bools could be packed together adjacently. I presume that that is theoretically ok? In contrast, if the sub-struct were named, you could presumably take the address of the entire sub-struct, so the space-inefficient offset to it is something you are just stuck with of course. A noob question: is it illegal to reorder the fields in a struct? (e.g. so as to optimise packing as far as correct alignment allows) - (C compatibility? Would perhaps need to be an _option_?)On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:Well obviously, because it adheres to explicit alignment. The compiler just has the wrong idea of how default alignment should work. Raised bug here, and I'm raising a PR now also. https://issues.dlang.org/show_bug.cgi?id=17237Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);With explicit align(32), it works: https://godbolt.org/g/3GjOHW - Johan
Mar 01 2017
On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:Iain, this of course is present in my version of LDC too. (I checked.) You couldn't poke David Nadlinger or whoever for me?On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:Well obviously, because it adheres to explicit alignment. The compiler just has the wrong idea of how default alignment should work. Raised bug here, and I'm raising a PR now also. https://issues.dlang.org/show_bug.cgi?id=17237Simple test case would be: struct vec_struct { bool b2; struct { bool b; int8 field; } } static assert(vec_struct.b.offsetof == 32); static assert(vec_struct.field.offsetof == 64);With explicit align(32), it works: https://godbolt.org/g/3GjOHW - Johan
Mar 02 2017
On Thursday, 2 March 2017 at 13:00:08 UTC, Cecil Ward wrote:Poke received ;-) Iain's fix is nicely small, so we can fast-forward it into LDC master. (probably best to create a small LDC issue for this, so it's not forgotten. Thanks a lot.) -JohanRaised bug here, and I'm raising a PR now also. https://issues.dlang.org/show_bug.cgi?id=17237Iain, this of course is present in my version of LDC too. (I checked.) You couldn't poke David Nadlinger or whoever for me?
Mar 02 2017