June 08, 2004
Regan Heath wrote:

> On Fri, 28 May 2004 16:15:06 +0800, J Anderson <REMOVEanderson@badmama.com.au> wrote:
>
>> Regan Heath wrote:
>>
>>> I thought I'd make this it's own little thread..
>>>
>>> I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying...
>>>
>>> struct foo {
>>>   int a;
>>>   int b;
>>>   int c;
>>> }
>>>
>>> int foobar(foo _a) {
>>>   foo a = _a;
>>> }
>>>
>>> I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.
>>>
>>
>> If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout.
>
>
> I was worried about efficiency, but also ... so you're saying D will pass my large structs by reference, not value?
>
> Ok, next question.
>
> If I pass a struct (it gets passed as an 'in' parameter by default) can the function modify it, what happens if it does? From what you say above it can have 2 different effects depending on whether the compiler optimized it or not.
>
> I think this is bad.
>
> I think 'in' should mean pass by reference AND cannot be modified. The latter causing a compile time error.
>
> Regan.

The effect shouldn't be visible.  If you modify the in struct, then the compiler *must* make a copy of it.  However if you don't modify it then the compiler has the choice at compile time.  I think about it like this, if the compiler can get away with it without making a side effect then it will.  As I said before pass by reference is often very inefficient.  If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.

BTW: I don't know how smart the dmd compiler is,  at the moment Walter may have used the simplest method and just make a byte copy although he has said that the above does work.

-- 
-Anderson: http://badmama.com.au/~anderson/
June 08, 2004
On Tue, 08 Jun 2004 09:36:04 +0800, J Anderson <REMOVEanderson@badmama.com.au> wrote:
> Regan Heath wrote:
>
>> On Fri, 28 May 2004 16:15:06 +0800, J Anderson <REMOVEanderson@badmama.com.au> wrote:
>>
>>> Regan Heath wrote:
>>>
>>>> I thought I'd make this it's own little thread..
>>>>
>>>> I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying...
>>>>
>>>> struct foo {
>>>>   int a;
>>>>   int b;
>>>>   int c;
>>>> }
>>>>
>>>> int foobar(foo _a) {
>>>>   foo a = _a;
>>>> }
>>>>
>>>> I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.
>>>>
>>>
>>> If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout.
>>
>>
>> I was worried about efficiency, but also ... so you're saying D will pass my large structs by reference, not value?
>>
>> Ok, next question.
>>
>> If I pass a struct (it gets passed as an 'in' parameter by default) can the function modify it, what happens if it does? From what you say above it can have 2 different effects depending on whether the compiler optimized it or not.
>>
>> I think this is bad.
>>
>> I think 'in' should mean pass by reference AND cannot be modified. The latter causing a compile time error.
>>
>> Regan.
>
> The effect shouldn't be visible.  If you modify the in struct, then the compiler *must* make a copy of it.

Yes. Otherwise you get side effects.

> However if you don't modify it then the compiler has the choice at compile time.  I think about it like this, if the compiler can get away with it without making a side effect then it will.

This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either:
- an inout incorrectly labelled as an in
- only going to be modified for the duration of the function, so why not an explicit copy as shown above.

So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.

> As I said before pass by reference is often very inefficient.

When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?

> If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.

Assuming pass-by-reference can be inefficient, I agree.

> BTW: I don't know how smart the dmd compiler is,  at the moment Walter may have used the simplest method and just make a byte copy although he has said that the above does work.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 08, 2004
Regan Heath wrote:

>
> Yes. Otherwise you get side effects.
>
>> However if you don't modify it then the compiler has the choice at compile time.  I think about it like this, if the compiler can get away with it without making a side effect then it will.
>
>
> This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either:
> - an inout incorrectly labelled as an in
> - only going to be modified for the duration of the function, so why not an explicit copy as shown above.

But the compiler can detect when its const and do it for you automaticly.  I think there is a place for const but not here.

> So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.

If you explicitly copy it then you are giving the compiler even more work (although the optimiser may be able to remove some of it).  That is you now have a reference copy and an array copy.

>
>> As I said before pass by reference is often very inefficient.
>
>
> When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?

What is often forgotten with references is that an extra memory location is required and things can't be kept in cache so well.
I'm not saying that copying a large struct is a good thing but copying a small structs (32 - 128 bits) can be.  It's best to test these theories out (as I have done previously in C++) out.  When you assign a reference you have to access the variable though the reference, rather then directly accessing it from the stack (which is on many cpus is automaticly cashed).  Quit often what happens is not what you think.

Keeping things in cache is a major field of optimisation these days considering its many times faster then ram. You don't want your program sitting around wasting cycles, waiting for some memory to be placed in cache.  Best let the compiler make the best choice about how to handle your code for these types of details.

>> If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.
>
> Assuming pass-by-reference can be inefficient, I agree.


I think const should go in somewhere but there still should be an in like operator somewhere.

-- 
-Anderson: http://badmama.com.au/~anderson/
June 08, 2004
On Tue, 08 Jun 2004 12:33:11 +0800, J Anderson <REMOVEanderson@badmama.com.au> wrote:
>> Yes. Otherwise you get side effects.
>>
>>> However if you don't modify it then the compiler has the choice at compile time.  I think about it like this, if the compiler can get away with it without making a side effect then it will.
>>
>>
>> This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either:
>> - an inout incorrectly labelled as an in
>> - only going to be modified for the duration of the function, so why not an explicit copy as shown above.
>
> But the compiler can detect when its const and do it for you automaticly.

Do what? throw a compile time error because you have just tried to modify it? that is what I want.

> I think there is a place for const but not here.

Why not, it seems the perfect place to me. The function designer knows what access they require to the input. That access should never change (if it did the fn would not be the same fn and would cause user code to behave strangely).

>> So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.
>
> If you explicitly copy it then you are giving the compiler even more work (although the optimiser may be able to remove some of it).  That is you now have a reference copy and an array copy.
>
>>
>>> As I said before pass by reference is often very inefficient.
>>
>>
>> When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?
>
> What is often forgotten with references is that an extra memory location is required and things can't be kept in cache so well.
> I'm not saying that copying a large struct is a good thing but copying a small structs (32 - 128 bits) can be.  It's best to test these theories out (as I have done previously in C++) out.  When you assign a reference you have to access the variable though the reference, rather then directly accessing it from the stack (which is on many cpus is automaticly cashed).  Quit often what happens is not what you think.

Good points.

> Keeping things in cache is a major field of optimisation these days considering its many times faster then ram. You don't want your program sitting around wasting cycles, waiting for some memory to be placed in cache.  Best let the compiler make the best choice about how to handle your code for these types of details.

I'm not saying I don't want the compiler to manage all that jazz.

What I am saying is that I think 'in' should imply const'ness and that I want the most efficient struct passing possible (which I *thought* was by reference - thank you for explaining)

>>> If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.
>>
>> Assuming pass-by-reference can be inefficient, I agree.
>
>
> I think const should go in somewhere but there still should be an in like operator somewhere.

The current 'in' doesn't do anything, why not change it to do something, like enforce constness.

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 08, 2004
Regan Heath wrote:

> On Tue, 08 Jun 2004 09:36:04 +0800, J Anderson
>> As I said before pass by reference is often very inefficient.
> 
> When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?

It definitely is faster if the data is needed only for the call:

------------
struct A {
        ...
}

A produce() {
        ...
}

void consume(A value) {
        ...
}

consume(produce());
------------

Unfortunately, this is something the compiler cannot decide by looking only at the routine, but it depends on the usage. Therefore, it should be left to the programmer to specify whether a struct should be passed by value or by reference. My suggestion would be the aforementioned idea: use "in" to indicate pass-by-reference and no modifier to indicate pass-by-value.

In the first case, we should forbid writing to the argument alltogether (effectively turning "in" into C++-style "const &"). Making a copy of a pass-by-reference argument never is as efficient as doing pass-by-value in the first place. If the programmer has to do the copying explicitely, it will be more obvious that there is some extra cost.

Of course, all of this does not matter if the compiler inlines the function, so it might be just as good to tell the programmer: if you care about performance, enable inlining...

June 08, 2004
J Anderson wrote:

> Best let the compiler make the best choice about how to handle your code for these types of details.

This is true in many contexts but not referring to calling conventions: The efficiency does not only depend on the internals of the routine but also on its use. If the compiler does inlining, it can do all the optimizations needed. Otherwise, there is no way to deduct which calling convention would be most efficient in general.

> I think const should go in somewhere but there still should be an in like operator somewhere.

What would you consider the difference between a "const" and an "in-like" operator?
June 09, 2004
Norbert Nemec wrote:

>J Anderson wrote:
>
>  
>
>>Best let the compiler make the best choice about how to handle
>>your code for these types of details.
>>    
>>
>
>This is true in many contexts but not referring to calling conventions: The
>efficiency does not only depend on the internals of the routine but also on
>its use. If the compiler does inlining, it can do all the optimizations
>needed. Otherwise, there is no way to deduct which calling convention would
>be most efficient in general.
>
>  
>
>>I think const should go in somewhere but there still should be an in
>>like operator somewhere.
>>    
>>
>
>What would you consider the difference between a "const" and an "in-like"
>operator?
>  
>
An in-like operator makes a copy and allows you to work on the copy.  A const like operator does not allow you to work on the copy (if indeed it is a copy).  I think this has been suggested before....

default - const in
in - like in now
out - like out now
inout - like inout now

That way you wouldn't have all those consts keywords floating around like Walter hates.  It wouldn't be to hard to convert existing programs.

-- 
-Anderson: http://badmama.com.au/~anderson/
1 2
Next ›   Last »