About structs and performant handling

deadalnix deadalnix at gmail.com
Sun Mar 10 11:55:39 PDT 2013


On Saturday, 9 March 2013 at 23:07:50 UTC, Ali Çehreli wrote:
> On 03/09/2013 12:19 PM, Namespace wrote:
>
> > But structs with a bigger size aren't that performant if you
> pass them
> > as copy or move them (See also my small benchmark:
>
> I have started working on the DConf presentation about copy and 
> move semantics in D. I have done exactly the same type of tests 
> and was surprised how faster pass-by-reference can be.
>
> To be fair, I have also accessed the members of the structs 
> inside the function to see whether the pointer dereferencing in 
> the by-ref case brought any cost. Apparently I have been 
> ignorant in modern CPU designs because I was surprised to see 
> that pointer dereferencing seemingly had no cost at all. My 
> guess would be that the object is completely inside the 
> processor's cache.
>

Have you checked the assembly to see if a dereference actually 
happened ?

This should be performant anyway, because the stack frame is 
likely to be in cache.

> Then I suspected dmd and made similar tests with gcc in the C 
> language and have seen similar results. So yes, apparently 
> by-ref is faster at least in some cases.
>

Indeed, if the struct is big enough or the copy expensive !

> > The compiler will check by these kind of parameters if they
> are structs
> > and if the size is proven greater as N (maybe 16 - 24) bit.
> If not, the
> > '&' will be ignored. The function take in this cases normally
> lvalues as
> > copy and moves rvalues.
> > But if the struct size is greater than N the compiler changes
> the
> > storage class of this parameter to ref.
>
> I hope others with compiler knowledge will chime in here.
>
> I think the type of the parameter that is passed is intrinsic 
> to how the function gets compiled. I think, for that to work, 
> the compiler would have to compile two versions of the 
> function, one taking by-value and the other taking by-ref.
>
> If what I said above is correct, then of course that wouldn't 
> scale, e.g. we would need four separate compilations of the 
> function if we had two parameters.
>

I don't think so. Many function's parameters aren't electible to 
such mecanism (or it'd be a bug) and many type don't gain to be 
passed by ref (small struct, like slice, delegate, a very large 
amount in fact).

> Then there would be the issue of finding a naming scheme for 
> these separate versions of the function so that the linker 
> finds the right one. I am making up some names for the linker: 
> foo_val_val(), foo_val_ref(), foo_ref_val(), foo_ref_ref().
>

Yes, mangling must be affected, but I don't think this is that 
bad.


More information about the Digitalmars-d mailing list