June 09, 2015
On Tuesday, 9 June 2015 at 13:13:53 UTC, Steven Schveighoffer wrote:
> It's actually faster to pass an rvalue by value, because it's constructed on the stack anyway.

I seriously doubt that's true for a large struct, e.g., something containing a large static array. Why move/copy the damn thing if I'm only going to read a tiny portion of it?

And please don't forget the ABI in that regard. E.g., on Win64, only POD types <= 64 bits (and whose size is a power of 2) are really passed by value (in a register or on the stack); all other types are passed as reference to a dedicated copy allocated on the caller's stack. So in this case, the indirection is enforced by the ABI anyway. If the callee is not going to modify the parameter, the copy should obviously be elided, falling back to classical byref passing.
June 09, 2015
On 6/9/15 10:53 AM, kink wrote:
> On Tuesday, 9 June 2015 at 13:13:53 UTC, Steven Schveighoffer wrote:
>> It's actually faster to pass an rvalue by value, because it's
>> constructed on the stack anyway.
>
> I seriously doubt that's true for a large struct, e.g., something
> containing a large static array. Why move/copy the damn thing if I'm
> only going to read a tiny portion of it?

Because it's not moved. It's written in the stack where it will be passed to the next function.

Then access to the data is done via stack pointer offsets instead of an extra indirection.

-Steve
June 09, 2015
On Tuesday, 9 June 2015 at 15:08:07 UTC, Steven Schveighoffer wrote:
> Because it's not moved. It's written in the stack where it will be passed to the next function.

Hmm, you mean the callee's function parameters stack? That's not always going to work, e.g., on Win64 the first 4 args are passed in registers, always. And, as I said, that ABI doesn't support byval passing of types > 64 bits (let's exclude vector types here), so rvalues > 64 bits can sadly not be constructed in-place without violating the Win64 ABI - they'll have to be passed byref.
June 09, 2015
On 6/9/15 12:23 PM, kink wrote:
> On Tuesday, 9 June 2015 at 15:08:07 UTC, Steven Schveighoffer wrote:
>> Because it's not moved. It's written in the stack where it will be
>> passed to the next function.
>
> Hmm, you mean the callee's function parameters stack? That's not always
> going to work, e.g., on Win64 the first 4 args are passed in registers,
> always.

If that's what's required, that's what we do. I'm not strictly saying that we will *always* do stack passing in spite of the ABI. But passing a large rvalue by value does not involve any moving of data, and can be abstracted to a pass by ref if needed. It's never less performing than an explicit pass by ref.

> And, as I said, that ABI doesn't support byval passing of types
>  > 64 bits (let's exclude vector types here), so rvalues > 64 bits can
> sadly not be constructed in-place without violating the Win64 ABI -
> they'll have to be passed byref.

I don't think we violate the Win64 ABI. So if it requires pass by ref, it requires pass by ref. I am not an expert in this matter. You may want to try some disassembly and see what D does.

-Steve
June 09, 2015
On Tuesday, 9 June 2015 at 17:38:00 UTC, Steven Schveighoffer wrote:
> But passing a large rvalue by value does not involve any moving of data, and can be abstracted to a pass by ref if needed. It's never less performing than an explicit pass by ref.

Thanks Steve.

The problem I see here on Win64 is that the current `auto ref` implementation for templates, i.e., 2^N function instantiations for N lvalue/rvalue combinations, seems totally useless for value types for which the ABI enforces pass-by-ref anyway.

In essence, `auto ref T` for templated functions on Win64 boils down to a simple `ref` accepting rvalue arguments iff T cannot be passed by value. All what's needed is constructing the rvalue on the caller's stack and destroying it after the call; the callee isn't affected at all, so no need for 2^N function versions, 1 is enough. Note that I haven't inspected the DMD code yet, but I assume it makes no exception for Win64 in that regard.

No opinions on the semantics for `in` I proposed earlier? `in T` would be something like a non-escapable `const auto ref T` accepting rvalues without codebloat and avoiding the indirection for small POD types T. Wouldn't that eliminate 99% of the use cases for `auto ref`, improve readability substantially and be the solution for all the C++ guys missing the rvalue-bindability of `const T&`?
June 09, 2015
> No opinions on the semantics for `in` I proposed earlier? `in T` would be something like a non-escapable `const auto ref T` accepting rvalues without codebloat and avoiding the indirection for small POD types T. Wouldn't that eliminate 99% of the use cases for `auto ref`, improve readability substantially and be the solution for all the C++ guys missing the rvalue-bindability of `const T&`?

'in' means 'const scope' and 'scope ref' together with 'in ref' was proposed in DIP 36 which was rejected. Let's see if Andrei thinks that my current work is satisfying. I hope so. :)
June 10, 2015
On Tuesday, 9 June 2015 at 20:25:28 UTC, Namespace wrote:
>> No opinions on the semantics for `in` I proposed earlier? `in T` would be something like a non-escapable `const auto ref T` accepting rvalues without codebloat and avoiding the indirection for small POD types T. Wouldn't that eliminate 99% of the use cases for `auto ref`, improve readability substantially and be the solution for all the C++ guys missing the rvalue-bindability of `const T&`?
>
> 'in' means 'const scope' and 'scope ref' together with 'in ref' was proposed in DIP 36 which was rejected. Let's see if Andrei thinks that my current work is satisfying. I hope so. :)

Can you point me to the justifications for the rejection? It should be pretty obvious that something like that is required. Personally, I'd go with `ref` being non-escapable by default and hence providing implicit rvalue-bindability, and having to use `escapable ref` if the parameter may escape and disallowing rvalues for these parameters. I know it's never gonna happen, it's just what I'd prefer.

I know what `in` currently means. Your proposed `in ref T` syntax is imo not much better than C++ `const T&`, so I'd prefer a simple and convenient `in T`. Semantics would be identical to your `in ref` with the additional optimization for small POD types. And for beginners, one could simply describe it as:
'Use the in keyword for a parameter if you're not going to mutate it. Don't rely on its identity as the argument may be passed by value or reference, whatever seems more efficient for the compiler and the target platform.'
June 11, 2015
On Wed, 10 Jun 2015 04:52:46 -0400, kink <noone@nowhere.com> wrote:

> I know what `in` currently means. Your proposed `in ref T` syntax is imo not much better than C++ `const T&`, so I'd prefer a simple and convenient `in T`. Semantics would be identical to your `in ref` with the additional optimization for small POD types. And for beginners, one could simply describe it as:
> 'Use the in keyword for a parameter if you're not going to mutate it. Don't rely on its identity as the argument may be passed by value or reference, whatever seems more efficient for the compiler and the target platform.'

+1

  Bit
June 12, 2015
On 09/06/2015 13:14, Namespace wrote:
<snip>
> What does this have to do with "garbage-collected language"?
> If I have a big struct, e.g.
> ----
> struct Matrix {
>      float[16] values = [...];
> }
> ----
> I always want to pass it by ref because a move or a copy would be too slow.

That seems to me a matter more of having something that behaves like C++ const T&, than of rvalue references as such.

Stewart.

-- 
My email address is valid but not my primary mailbox and not checked regularly.  Please keep replies on the 'group where everybody may benefit.
June 12, 2015
On Friday, 12 June 2015 at 19:39:25 UTC, Stewart Gordon wrote:
> On 09/06/2015 13:14, Namespace wrote:
> <snip>
>> What does this have to do with "garbage-collected language"?
>> If I have a big struct, e.g.
>> ----
>> struct Matrix {
>>      float[16] values = [...];
>> }
>> ----
>> I always want to pass it by ref because a move or a copy would be too slow.
>
> That seems to me a matter more of having something that behaves like C++ const T&, than of rvalue references as such.
>
> Stewart.

Yes, you could say that. It is implemented in this manner.
1 2 3 4 5 6
Next ›   Last »