October 24, 2012 Re: long compile time question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On Wednesday, October 24, 2012 21:35:22 Manfred Nowak wrote:
> Dan wrote:
> > The following takes nearly three minutes to compile.
>
> ... and this returns immediately:
>
> --------------------------------
> struct B {
> const size_t SIZE = 1024*64;
> int[SIZE] x= void; // !!!
> }
>
> void main() {
> B[] barr;
> barr ~= B();
> }
> -------------------------------
> - manfred
That's incredibly dangerous though, because than B.init has garbage in it. Still, it's interesting that it would affect the speed. Maybe the compiler recognizes that it's garbage and so doesn't bother copying it (meaning that you'll get different garbage for every use of B.init).
- Jonathan M Davis
|
October 24, 2012 Re: long compile time question | ||||
---|---|---|---|---|
| ||||
Posted in reply to thedeemon | On Wednesday, 24 October 2012 at 15:39:19 UTC, thedeemon wrote:
> The code DMD generates for initializing the struct does not use loops, so it's
> xor ecx, ecx
> mov [eax], ecx
> mov [eax+4], ecx
> mov [eax+8], ecx
> ...
>
> So your code creates a lot of work for the compiler.
That seems silly. I would think after the struct's init/contents were known it would make a single block that holds the basic init for it and bulk copy every time it needed it (if it's beyond a certain size, say 32 bytes).
Also memset only works if the data can be defaulted to 0. Hmmm...
|
October 24, 2012 Re: long compile time question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | On Thu, Oct 25, 2012 at 12:05:25AM +0200, Era Scarecrow wrote: > On Wednesday, 24 October 2012 at 15:39:19 UTC, thedeemon wrote: > >The code DMD generates for initializing the struct does not use > >loops, so it's > >xor ecx, ecx > >mov [eax], ecx > >mov [eax+4], ecx > >mov [eax+8], ecx > >... > > > >So your code creates a lot of work for the compiler. > > That seems silly. I would think after the struct's init/contents > were known it would make a single block that holds the basic init > for it and bulk copy every time it needed it (if it's beyond a > certain size, say 32 bytes). > > Also memset only works if the data can be defaulted to 0. Hmmm... Not true. Memset is *usually* used to set memory to 0, but it can set memory to other byte values too. Although this doesn't help if the .init value isn't something consisting of repeated byte values. In any case, though, separately initializing every member of an array is silly. That's what a loop is for. That, or a memcpy from an immutable copy of .init. T -- Life would be easier if I had the source code. -- YHL |
October 27, 2012 Re: long compile time question | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh |
>
> In any case, though, separately initializing every member of an array is
> silly. That's what a loop is for. That, or a memcpy from an immutable
> copy of .init.
I think that the reasoning behind DMD's implementation is that for small structs, writing out the instructions is more efficient than a loop or a memcpy(); it's essentially the equivalent of loop unrolling and function inlining. However, that reasoning breaks down as soon as the struct's size goes beyond a certain value.
In my opinion, though, this behavior should be kept for small structs. For example, if you have a struct that just wraps a size_t, just generating a move instruction is _way_ faster than a call to memcpy().
|
October 27, 2012 Re: long compile time question | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLM768 | On Saturday, 27 October 2012 at 23:07:19 UTC, BLM768 wrote:
>
>>
>> In any case, though, separately initializing every member of an array is
>> silly. That's what a loop is for. That, or a memcpy from an immutable
>> copy of .init.
>
> I think that the reasoning behind DMD's implementation is that for small structs, writing out the instructions is more efficient than a loop or a memcpy(); it's essentially the equivalent of loop unrolling and function inlining. However, that reasoning breaks down as soon as the struct's size goes beyond a certain value.
> In my opinion, though, this behavior should be kept for small structs. For example, if you have a struct that just wraps a size_t, just generating a move instruction is _way_ faster than a call to memcpy().
I just realized that this post is redundant; other posts have also mentioned optimization for small structs. That makes two relatively dumb posts from me in a day; maybe I should just stop for now. :)
|
Copyright © 1999-2021 by the D Language Foundation