Google Groups Home
Help | Sign in
Message from discussion Mini ray tracer
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
Jon Harrop  
View profile
 More options 10 May 2005, 16:17
Newsgroups: comp.graphics.rendering.raytracing
From: Jon Harrop <use...@jdh30.plus.com>
Date: Tue, 10 May 2005 16:17:23 +0100
Local: Tues 10 May 2005 16:17
Subject: Re: Mini ray tracer

Warp wrote:
> Jon Harrop <use...@jdh30.plus.com> wrote:
>> My post is more about clarity and less about performance. Your proposed
>> alterations make the C++ implementation significantly longer and more
>> obfuscated and your littering of the source code with "inline" actually
>> slows the program down on my Athlon t-bird.

>   Then your compiler is stupid. Get a better one.
> ...

I agree that the compiler is stupid but I'm comparing g++ as this is a
common compiler. A better C++ compiler is likely to produce faster code, of
course.

>   And by the way, if you are afraid of "litter" in C++ code, then you
> should switch to another programming language.

Absolutely. :-)

>   That "litter", as you call it, is not useless junk as you seem to imply.
> It has a reason and a significance.

It also has unexpected platform dependent results, as "tbp" has discovered.

>> > b) more importantly he's passing large structures by _value_ and i've
>> > turned them into _references_.

>> Both implementations use pass by value as this is clearer, shorter and
>> (as a consequence) more common in real code.

>   I hope you are not passing megabyte-sized vectors by value...

No, they are small, constant-sized vectors (3D), so pass by value does not
affect the asymptotic algorithmic complexity.

>   If your opinion of "clearer" and "shorter" is that the & symbol should
> not be used, then you might want to either check your priorities or
> change your programming language (because C++ is not for you).

Unfortunately, you cannot just use "&" because it will take a reference to a
temporary, giving an error like:

ray.cpp: In member function `virtual void Sphere::intersect(double&, Vec&,
Ray)
   ':
ray.cpp:39: error: no match for 'operator+' in 'ray.Ray::orig +
   operator*(double, Vec)(((&ray) + 24))'
ray.cpp:12: error: candidates are: Vec operator+(Vec&, Vec&)
/usr/include/c++/3.3/bits/stl_bvector.h:261: error:
   std::_Bit_const_iterator std::operator+(int, const
   std::_Bit_const_iterator&)
/usr/include/c++/3.3/bits/stl_bvector.h:202: error:
   std::_Bit_iterator std::operator+(int, const std::_Bit_iterator&)
ray.cpp: In function `double ray_trace(double, Vec, Ray, Scene*)':
ray.cpp:62: error: no match for 'operator+' in 'ray.Ray::orig +
   operator*(double, Vec)(((&ray) + 24))'
ray.cpp:12: error: candidates are: Vec operator+(Vec&, Vec&)
/usr/include/c++/3.3/bits/stl_bvector.h:261: error:
   std::_Bit_const_iterator std::operator+(int, const
   std::_Bit_const_iterator&)
/usr/include/c++/3.3/bits/stl_bvector.h:202: error:
   std::_Bit_iterator std::operator+(int, const std::_Bit_iterator&)

You must either use "const ... &" instead, or make sure that all values are
created explicitly as local variables in the caller (rather than being
inline subexpressions in the function call).

It is precisely this obfuscation (and the fact that these are tiny
structures, and that this is not necessarily an optimisation, and that it
could be done by the compiler) that made me choose pass by value.

>> If you want a fair comparison then you should also make equivalent
>> changes to the OCaml implementation.

>   You want to compare which programming language runs inefficient code
> faster?

If you completely optimise both implementations then you'll end up with the
same assembler. There is only value in comparing simpler implementations in
both languages. So yes, they will not be completely optimised but
subjectively "like" real code.

>> I chose an inheritance hierarchy because this is the closest C++
>> equivalent to a variant type which I see in typical C++ programs.

>   Inheritance has no overhead in C++. Dynamic binding has.
>   While virtual function calls are pretty fast they are still slightly
> slower than regular function calls. If you want maximum speed you should
> not make time-critical functions virtual unless you are really forced to.

I believe I am "really forced to" as virtual lookup is used instead of
switching on the tag of the variant type/union. In C++, virtual functions
are more elegant (and more common in real code) than C-style tagged unions.

>> Another optimisation that I made was to replace inheritance with a single
>> Scene struct which represented a group of child scenes or a sphere when
>> it had no children.

>   Inheritance causes no overhead. That kind of optimization is useless.

Getting rid of inheritance gets rid of the virtual functions. However, it
necessarily incurs an equivalent test somewhere else.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google