Performance improvements for D / DMD compiler.
janderson
askme at me.com
Sat Jan 20 01:09:10 PST 2007
Walter Bright wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> No, and for a good reason:
>>
>> foo(LargeStruct s1, LargeStruct s2)
>> {
>> ...
>> }
>> ...
>> LargeStruct s;
>> foo(s, s);
>>
>> Nobody would enjoy hidden aliasing of s1 and s2.
I think you mean more like:
foo(LargeStruct s1, LargeStruct inout s2)
{
...
}
...
LargeStruct s;
foo(s, s);
In cases where there is an inout, I think the compiler would have to
fallback on the old one. The one below that Walter pointed out is more
troublesome.
>
> There's another aliasing case:
>
> LargeStruct s;
> foo(s);
> ... here some other thread modifies s ...
>
> And foo() suddenly has its argument values change unexpectedly.
>
> Value and reference type usages mostly overlap, but they are
> fundamentally different, and having the compiler switch between the two
> in some implementation-defined manner (as suggested by others more than
> once) is not going to work.
>
> If one is needing reference behavior from a struct, seriously consider
> making it a class instead. Or even just take the address of it and pass
> the pointer.
I never thought about that one. Of course your right about this like
normal. Humm... what about copy on read/write...
struct A
{
byte[100] b;
}
//My contrived example
void foo(in A x, in A y)
{
if (g)
{
if (x)
{
//...
}
else
{
if (y)
{
//...
}
}
}
}
//Would convert too.
void foo(inout A x, inout A y) //Both treated as in/out
{
if (g)
{
A x2 = x; //First time x is used
if (x2)
{
//...
}
else
{
A y2 = y; //First time y is used
if (y2)
{
//...
}
}
}
}
if (g) was false you would avoid the expensive copy of x2 to the stack.
Of course the tricky part is working out when this optimisation is
worth it. The function could actually run slower because there are 2
more values on the stack.
Ok, I spotted a floor in that design also. A thread event could occur
between the copy of x2 and y2 (or at g). I guess this would mean the
user would have to somehow indicate that that is ok.
Ok here's yet another idea.
void bar(in A a)
{
//....
}
void foo(in A a)
{
bar(a);
bar(a);
}
In this example we already have an in copy of A, so why copy it again?
We do not have a reference and foo isn't doing any threading operations.
If this was inlined it would be optimized away, however if it can't be
inlined it should still be possible to optimize it away.
//Here's another example of the some thing
void foo()
{
A a;
bar(a);
//End of function A goes out of scope and A is destroyed.
}
-Joel
More information about the Digitalmars-d
mailing list