www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Inlining Code Test

reply bearophile <bearophileHUGS lycos.com> writes:
Nick Voronin:

 Looks like alignment of local variables is somewhat broken.

This is a very nice bug. If not already present then please add it to Bugzilla. If you don't want to add it, then I will add it myself. I have modified your code like this: import core.stdc.stdio: printf; void main() { int a; double d; printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8); } And this shows the performance difference: import core.stdc.stdio: printf; import std.date: getUTCtime, ticksPerSecond; void main() { double d = 0.0; auto t0 = getUTCtime(); for (size_t i = 0; i < 100_000_000; i++) d += 1; auto t1 = getUTCtime(); printf("%lf\n", d); printf("%u\n", (cast(size_t)&d) % 8); printf("%lf\n", (cast(double)t1 - cast(double)t0) / ticksPerSecond); } Bye, bearophile
Dec 17 2010
next sibling parent reply "Nick Voronin" <elfy.nv gmail.com> writes:
I found this on bugzilla.
http://d.puremagic.com/issues/show_bug.cgi?id=2278

So it's not really a bug. Yet there is no simple workaround. And gap  
between int and double looks strange when stack frame itself is unaligned.

btw, is there no explicit alignment for variables in D at all?
align(8) double d; compiles if d is global, but it does nothing.

import core.stdc.stdio: printf;

align(8) int a;
align(8) double d;

void main() {
     printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8);
}

This _always_ prints "4 4" for me. It seems that globals are not affected  
by environment, but not aligned anyway.

Honestly, I'm lost :) It all works not as expected but then again I can't  
find any evidences that my expectations are valid.

On Sat, 18 Dec 2010 01:57:44 +0300, bearophile <bearophileHUGS lycos.com>  
wrote:

 Nick Voronin:

 Looks like alignment of local variables is somewhat broken.

This is a very nice bug. If not already present then please add it to Bugzilla. If you don't want to add it, then I will add it myself. I have modified your code like this: import core.stdc.stdio: printf; void main() { int a; double d; printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8); } And this shows the performance difference: import core.stdc.stdio: printf; import std.date: getUTCtime, ticksPerSecond; void main() { double d = 0.0; auto t0 = getUTCtime(); for (size_t i = 0; i < 100_000_000; i++) d += 1; auto t1 = getUTCtime(); printf("%lf\n", d); printf("%u\n", (cast(size_t)&d) % 8); printf("%lf\n", (cast(double)t1 - cast(double)t0) / ticksPerSecond); } Bye, bearophile

-- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 17 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Nick Voronin:

 I found this on bugzilla.
 http://d.puremagic.com/issues/show_bug.cgi?id=2278
 
 So it's not really a bug.

It's borderline a performance bug. You may add that code to the issue 2278 as further examples. Bye, bearophile
Dec 17 2010
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Nick Voronin wrote:
 I found this on bugzilla.
 http://d.puremagic.com/issues/show_bug.cgi?id=2278
 
 So it's not really a bug. Yet there is no simple workaround. And gap 
 between int and double looks strange when stack frame itself is unaligned.

Interestingly, since I filed that bug, DMD for MacOSX was created, which ensures that the stack stays aligned in the way I described! So the DMD backend is perfectly capable of doing it now.
 btw, is there no explicit alignment for variables in D at all?
 align(8) double d; compiles if d is global, but it does nothing.

That's a regression. Large globals are always aligned to a 16-byte boundary (see changelog for 2.007) However this code: import core.stdc.stdio: printf; int a; double[4] d; void main() { printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8); } shows that it stopped doing that somewhere between 2.027 and 2.030.
Dec 17 2010
parent Don <nospam nospam.com> writes:
Nick Voronin wrote:
 On Sat, 18 Dec 2010 02:17:46 +0100
 Don <nospam nospam.com> wrote:
 
 Nick Voronin wrote:
 btw, is there no explicit alignment for variables in D at all?
 align(8) double d; compiles if d is global, but it does nothing.

boundary (see changelog for 2.007)

On second thought large globals in static segment (as log says) are probably only those with __gshared prefix. And they do look aligned.

Good catch! Yes, that makes perfect sense. So the bug is that align() is ignored for TLS variables.
Dec 20 2010
prev sibling parent "Nick Voronin" <elfy.nv gmail.com> writes:
On Sat, 18 Dec 2010 04:17:46 +0300, Don <nospam nospam.com> wrote:

 Interestingly, since I filed that bug, DMD for MacOSX was created, which  
   ensures that the stack stays aligned in the way I described! So the  
 DMD backend is perfectly capable of doing it now.

I added some examples to that bugreport. Just in case :)
 btw, is there no explicit alignment for variables in D at all?
 align(8) double d; compiles if d is global, but it does nothing.

That's a regression. Large globals are always aligned to a 16-byte boundary (see changelog for 2.007) However this code: import core.stdc.stdio: printf; int a; double[4] d; void main() { printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8); } shows that it stopped doing that somewhere between 2.027 and 2.030.

Thanks. Filed it as http://d.puremagic.com/issues/show_bug.cgi?id=5355 -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 17 2010
prev sibling parent Nick Voronin <elfy.nv gmail.com> writes:
On Sat, 18 Dec 2010 02:17:46 +0100
Don <nospam nospam.com> wrote:

 Nick Voronin wrote:
 btw, is there no explicit alignment for variables in D at all?
 align(8) double d; compiles if d is global, but it does nothing.

That's a regression. Large globals are always aligned to a 16-byte boundary (see changelog for 2.007)

On second thought large globals in static segment (as log says) are probably only those with __gshared prefix. And they do look aligned.
 However this code:
 
 import core.stdc.stdio: printf;
 
 int a;
 double[4] d;
 
 void main() {
      printf("%u %u\n", (cast(size_t)&a) % 8, (cast(size_t)&d) % 8);
 }
 shows that it stopped doing that somewhere between 2.027 and 2.030.

-- Nick Voronin <elfy.nv gmail.com>
Dec 18 2010