August 07, 2021

On Friday, 6 August 2021 at 22:15:00 UTC, Paul Backus wrote:

>

On Friday, 6 August 2021 at 19:03:53 UTC, Tejas wrote:

>

Stealing Paul's answer now:

import std;

enum your_max_length = 1000;
enum your_align = 256;
struct MySlice(T/*, size_t maxLength*/)
{
    private align(your_align)T payload;

    //invariant(payload.length <= maxLength);

    //this(T[] slice) { payload = slice; }

    //T opIndex(size_t i) { return payload[i]; }
}
void main()
{
   MySlice!(int/*, 1000*/)[your_max_length] slice;
    writeln(slice.sizeof);
}

You can actually pass the alignment as a parameter too:

struct Aligned(T, size_t alignment)
    if (alignment >= T.alignof)
{
    align(alignment) T payload;
    alias payload this;
}

void main()
{
    Aligned!(int, 16)[4] x;
    assert(x.alignof == 16);
    assert(x.sizeof == 64);

    Aligned!(int[4], 16) y;
    assert(y.alignof == 16);
    assert(y.sizeof == 16);
}

Is the second example really correct? if the alignment of int[4] really is 16, then why isn't the size of it 64 as well? It seems that the alignment constraint is not being satisfied within the array,

And if it really is correct, then it seems once again that static arrays are the answer after all:

align(your_alignment) int[your_length] array;

No need for structs \('_')/

August 07, 2021

On Saturday, 7 August 2021 at 07:32:04 UTC, Tejas wrote:

>

And if it really is correct, then it seems once again that static arrays are the answer after all:

align(your_alignment) int[your_length] array;

No need for structs \('_')/

The main advantage of the struct is that you can heap-allocate it:

auto array = new Aligned!(int[4], 16);
August 07, 2021

On Saturday, 7 August 2021 at 12:08:00 UTC, Paul Backus wrote:

>

On Saturday, 7 August 2021 at 07:32:04 UTC, Tejas wrote:

>

And if it really is correct, then it seems once again that static arrays are the answer after all:

align(your_alignment) int[your_length] array;

No need for structs \('_')/

The main advantage of the struct is that you can heap-allocate it:

auto array = new Aligned!(int[4], 16);

First, thanks all for helping with this question!

The simple desire to arbitrarily align an array is certainly looking non-trivial.
Below is a simple program of both the suggested "struct" and "align array" solutions.
Unfortunately, neither is guaranteed to place the array with the desired alignnment.

import std.stdio;
enum ALIGNMENT=64;
enum LENGTH=10;

struct Aligned(T, size_t alignment) if (alignment >= T.alignof)
{
   align(alignment) T payload;
   alias payload this;
}

void main()
{
   writeln("ALIGNMENT:  ", ALIGNMENT, ",\t\tLENGTH:  ", LENGTH);

   int[23] junk;
   align(ALIGNMENT) int[LENGTH] z;

   writeln("\nusing 'align(ALIGNMENT) int[LENGTH] z;'");
   writeln("\ncast(ulong) z.ptr%ALIGNMENT:  ", cast(ulong) z.ptr%ALIGNMENT);
   writeln("int.alignof:  ", int.alignof, ",\tint.sizeof:  ", int.sizeof);

   writeln("&z[0]", &z[0]);
   writeln("&z[1]", &z[1]);
   writeln("&z[2]", &z[2]);

   writeln("\nusing:  'Aligned!(int, ALIGNMENT)[LENGTH] x;'");
   Aligned!(int, ALIGNMENT)[LENGTH] x;

   writeln("x.sizeof:  ", x.sizeof, "\t\tx.alignof:  ", x.alignof);
   writeln("x:  ", x);

   writeln("\nx.ptr:  ", x.ptr);
   writeln("&x[0]", &x[0]);
   writeln("&x[1]", &x[1]);
   writeln("&x[2]", &x[2]);
   writeln("\ncast(ulong) x.ptr%ALIGNMENT:  ", cast(ulong) x.ptr%ALIGNMENT);
}

and here is a sample output of a run:

ALIGNMENT: 64, LENGTH: 10

using 'align(ALIGNMENT) int[LENGTH] z;'

cast(ulong) z.ptr%ALIGNMENT: 32
int.alignof: 4, int.sizeof: 4
&z[0]7FFFF8D05B60
&z[1]7FFFF8D05B64
&z[2]7FFFF8D05B68

using: 'Aligned!(int, ALIGNMENT)[LENGTH] x;'
x.sizeof: 640 x.alignof: 64
x: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

x.ptr: 7FFFF8D05B90
&x[0]7FFFF8D05B90
&x[1]7FFFF8D05BD0
&x[2]7FFFF8D05C10

cast(ulong) x.ptr%ALIGNMENT: 16


Notice, that neither attempt yields an array starting address as
zero modulo the alignment value ...

Also, a bit weird is that the "align array" solution yields expected
spacing between array elements, but the "struct" solution has wider
separations ...


Again, I am very appreciative of your replies and help with this.
I have learned quite a bit from this discussion. However, I remain
a bit stumped by all of this....

Any ideas out there?

Best Regards,
James

August 07, 2021

On Saturday, 7 August 2021 at 13:36:52 UTC, james.p.leblanc wrote:

>

On Saturday, 7 August 2021 at 12:08:00 UTC, Paul Backus wrote:

>

[...]

First, thanks all for helping with this question!

The simple desire to arbitrarily align an array is certainly looking non-trivial.
Below is a simple program of both the suggested "struct" and "align array" solutions.
Unfortunately, neither is guaranteed to place the array with the desired alignnment.

[...]

Umm, the align array solution is flat out wrong, please ignore it. Most likely a bug in the compiler.

Also, why will the address of the first element of the array modulo alignment be 0? The address of the array has absolutely nothing to do with the alignment.

You say that the align array solution has the expected spacing, but it is default aligned, totally ignoring your 64 byte requirement.

Don't use x.PTR%ALIGNMENT
Use (&x[1]-&[2])%ALIGNMENT

You will get ALIGNMENT*(2 -1)(since you took difference of 2nd and 1st elem)

August 07, 2021

On Saturday, 7 August 2021 at 13:36:52 UTC, james.p.leblanc wrote:

>

On Saturday, 7 August 2021 at 12:08:00 UTC, Paul Backus wrote:

>

[...]

First, thanks all for helping with this question!

The simple desire to arbitrarily align an array is certainly looking non-trivial.
Below is a simple program of both the suggested "struct" and "align array" solutions.
Unfortunately, neither is guaranteed to place the array with the desired alignnment.

[...]

If you don't believe me just subtract the adresses yourself:

x.ptr: 7FFFF8D05B90
&x[0]7FFFF8D05B90
&x[1]7FFFF8D05BD0
&x[2]7FFFF8D05C10

&x[1] 7FFFF8D05BD0
-&x[0] -7FFFF8D05B90


    000000000040

0X40 = 64 in base 10

Your alignment requirement was 64 bytes

August 07, 2021

On Saturday, 7 August 2021 at 14:34:49 UTC, Tejas wrote:

>

Umm, the align array solution is flat out wrong, please ignore it. Most likely a bug in the compiler.

Also, why will the address of the first element of the array modulo alignment be 0? The address of the array has absolutely nothing to do with the alignment.

You say that the align array solution has the expected spacing, but it is default aligned, totally ignoring your 64 byte requirement.

Don't use x.PTR%ALIGNMENT
Use (&x[1]-&[2])%ALIGNMENT

You will get ALIGNMENT*(2 -1)(since you took difference of 2nd and 1st elem)

For the array as a whole to be aligned, not only must the spacing between the elements respect the alignment, but starting address of the array itself must be a multiple of the alignment. So it is correct to check that x.ptr%ALIGNMENT == 0.

The issue with align attributes being ignored for stack variables is apparently a known bug, first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16098

The issue with align attributes being ignored by new is also a known bug, and was also first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16508

August 07, 2021

On Saturday, 7 August 2021 at 15:21:01 UTC, Paul Backus wrote:

>

On Saturday, 7 August 2021 at 14:34:49 UTC, Tejas wrote:

>

[...]

For the array as a whole to be aligned, not only must the spacing between the elements respect the alignment, but starting address of the array itself must be a multiple of the alignment. So it is correct to check that x.ptr%ALIGNMENT == 0.

The issue with align attributes being ignored for stack variables is apparently a known bug, first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16098

The issue with align attributes being ignored by new is also a known bug, and was also first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16508

Oh wow, and here I thought I was being smart :(

So, how can we work around this without assembly language magic? I'm illiterate at assembly.

August 07, 2021

On Saturday, 7 August 2021 at 15:41:24 UTC, Tejas wrote:

>

On Saturday, 7 August 2021 at 15:21:01 UTC, Paul Backus wrote:

>

The issue with align attributes being ignored for stack variables is apparently a known bug, first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16098

The issue with align attributes being ignored by new is also a known bug, and was also first reported in 2016: https://issues.dlang.org/show_bug.cgi?id=16508

Oh wow, and here I thought I was being smart :(

So, how can we work around this without assembly language magic? I'm illiterate at assembly.

For stack allocations, you can use the workaround in Vladimir Panteleev's comment (ignoring the ASM part, which is unrelated to alignment).

For heap allocations, I guess the easiest way would be to use AlignedMallocator from std.experimental.allocator.

August 08, 2021

On Saturday, 7 August 2021 at 19:07:04 UTC, Paul Backus wrote:

>

On Saturday, 7 August 2021 at 15:41:24 UTC, Tejas wrote:

>

On Saturday, 7 August 2021 at 15:21:01 UTC, Paul Backus wrote:

>

[...]

Oh wow, and here I thought I was being smart :(

So, how can we work around this without assembly language magic? I'm illiterate at assembly.

For stack allocations, you can use the workaround in Vladimir Panteleev's comment (ignoring the ASM part, which is unrelated to alignment).

For heap allocations, I guess the easiest way would be to use AlignedMallocator from std.experimental.allocator.

Cool... thanks

August 08, 2021

On Sunday, 8 August 2021 at 02:00:26 UTC, Tejas wrote:

>

On Saturday, 7 August 2021 at 19:07:04 UTC, Paul Backus wrote:

>

On Saturday, 7 August 2021 at 15:41:24 UTC, Tejas wrote:

>

On Saturday, 7 August 2021 at 15:21:01 UTC, Paul Backus wrote:

>

[...]

Oh wow, and here I thought I was being smart :(

So, how can we work around this without assembly language magic? I'm illiterate at assembly.

For stack allocations, you can use the workaround in Vladimir Panteleev's comment (ignoring the ASM part, which is unrelated to alignment).

For heap allocations, I guess the easiest way would be to use AlignedMallocator from std.experimental.allocator.

Cool... thanks

Thanks to everyone for all of the great discussion and hints on this topic!

I have learned quite much, and have a gained an understanding on
how to use D effectively.

Fantastic forum here on a great language.

Best Regards,
James

1 2
Next ›   Last »