November 08, 2007 Re: Raytracing speed again, this time with gdc. | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | downs wrote:
> I've tried to translate the attached C++ program to D (D program also
> attached).
>
> Even after explicitly using the __builtin_sqrt (which correctly
> generates a fsqrt instruction (shame on you, non-inlined std.math)), the
> D code is significantly slower (12.9s for D vs 9s for C++).
>
> Does anybody know why this is so?
> --downs, confused and saddened
>
> PS: benchmark
>
> gentoo-pc ~/d/RayBen $ gdc ray1.d -O3 -frelease -ffast-math -o ray1_d
> tools/base.d && time ./ray1_d >result_d.pnm; g++ ray1.cxx -O3
> -ffast-math -o ray1_cpp && time ./ray1_cpp > result_cxx.pnm
>
> real 0m13.448s
> user 0m12.730s
> sys 0m0.090s
>
> real 0m10.128s
> user 0m9.810s
> sys 0m0.020s
>
Could the difference be in part due to default initialization in D? Maybe all your rays and vecs are getting initialized first to NaN and then overwritten with the value you want, and that is slowing it down.
You could try sticking some =void's in your structs, like so:
struct Vec {
double x=void, y=void, z=void;
Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); }
Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); }
Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; }
Vec unitise() { return opMul(1.0/dsqrt(dot(*this))); }
}
struct Pair(T, U) { T first=void; U second=void; }
typedef Pair!(double, Vec) Hit;
struct Ray { Vec orig=void, dir=void; }
--bb
|
November 09, 2007 Re: Raytracing speed again, this time with gdc. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote:
>
> Could the difference be in part due to default initialization in D? Maybe all your rays and vecs are getting initialized first to NaN and then overwritten with the value you want, and that is slowing it down.
>
> You could try sticking some =void's in your structs, like so:
>
> struct Vec {
> double x=void, y=void, z=void;
> Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); }
> Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); }
> Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
> double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; }
> Vec unitise() { return opMul(1.0/dsqrt(dot(*this))); }
> }
>
> struct Pair(T, U) { T first=void; U second=void; }
> typedef Pair!(double, Vec) Hit;
>
> struct Ray { Vec orig=void, dir=void; }
>
>
> --bb
If you check the source, you'll see that practically all my structs are either
manually initialized with proper values or the result of a calculation. Also,
I tried that and it's not it.
Sorry.
Still, thanks for the idea!
--downs
|
November 10, 2007 Re: Raytracing speed again, this time with gdc. | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | Any success? If you find out what it was could you post it? The only things I can think of are a stack heap allocation, variable initialisation and better optimization differences... Maybe making some smaller test cases. |
November 10, 2007 Re: Raytracing speed again, this time with gdc. | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | "downs" <default_357-line@yahoo.de> wrote in message news:fh0iem$2dhc$1@digitalmars.com... > Bill Baxter wrote: >> >> Could the difference be in part due to default initialization in D? >> Maybe all your rays and vecs are getting initialized first to NaN and >> then overwritten with the value you want, and that is slowing it down. >> >> You could try sticking some =void's in your structs, like so: >> >> struct Vec { >> double x=void, y=void, z=void; >> Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); } >> Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); } >> Vec opMul(double a) { return Vec(x*a, y*a, z*a); } >> double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; } >> Vec unitise() { return opMul(1.0/dsqrt(dot(*this))); } >> } >> >> struct Pair(T, U) { T first=void; U second=void; } >> typedef Pair!(double, Vec) Hit; >> >> struct Ray { Vec orig=void, dir=void; } >> >> >> --bb > > If you check the source, you'll see that practically all my structs are either > manually initialized with proper values or the result of a calculation. Also, > I tried that and it's not it. > Sorry. > > Still, thanks for the idea! > --downs Sorry if this has already been discussed, but if not: Have you checked to see if function inlining differences are the culprit? The D front-end doesn't inline functions with byref params, and for DMD at least the FE is responsible for all inlining. For GDC the front-end inlining might be turned off anyhow (I can't remember), and maybe GCC does all that in the intermediate or backend stages.. If so it would presumably be pretty close to the same for D and C++ but it might be worth a look anyhow. |
Copyright © 1999-2021 by the D Language Foundation