MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Mathematica 7 is now available

  • To: mathgroup at smc.vnet.net
  • Subject: [mg94426] Re: Mathematica 7 is now available
  • From: Jon Harrop <jon at ffconsultancy.com>
  • Date: Fri, 12 Dec 2008 06:57:51 -0500 (EST)
  • References: <gg62p3$56g$1@smc.vnet.net> <gh8hkr$r1d$1@smc.vnet.net> <ghavsp$ock$1@smc.vnet.net> <200812081121.GAA15802@smc.vnet.net> <ghlmbp$jof$1@smc.vnet.net> <200812100949.EAA00307@smc.vnet.net> <ghqk4i$193$1@smc.vnet.net>

On Wednesday 10 December 2008 16:22:15 Daniel Lichtblau wrote:
> Jon Harrop wrote:
> > Daniel Lichtblau wrote:
> >> Jon Harrop wrote:
> >>> This is not specific to OCaml. Here are equivalent implementations of
> >>> that program in C++, Java, OCaml, SML, Scheme, Lisp and Haskell and
> >>> all 
> >>> well over 100,000x faster than the Mathematica I gave (and many are
> >>> more concise as well!):
> >>>
> >>>   http://www.ffconsultancy.com/languages/ray_tracer/
> >>
> >> I do not understand this claim that the speed difference is 5 orders of
> >> magnitude. Some experiments indicate 3, perhaps.
> >
> > The code I gave is over 5 orders of magnitude slower by my measurements.
>
> Offhand I do not know what would account for this. I ran it in
> Mathematica 7 (a 64 bit Linux machine) on
>
> Main[3, 52, 4]
>
> and observed something around 7-10 times slower than what I coded.

You'll get completely different performance results if you lower the first 
argument because it changes the scene being rendered. You're only rendering
a handful of spheres with those arguments whereas the original rendered
over 80,000 spheres.

With 9,512,1 your version is 170x faster than my code, which took 26,000 
seconds here. The original arguments 9,512,4 would take 16x longer still, 
meaning your code is still 640x slower than the fastest compiled languages.
That is the five orders of magnitude I was referring to.

> I did 
> not try it on larger scenes, so possibly there is something going wrong
> in the recursion. Certainly any of these codes will scale linearly with
> the number of pixels (so quadratically with n), so my using a dimension
> of 52 instead of 512 here should not matter for assessment of relative
> speeds.

I'd recommend cutting ss down to 1 before reducing the resolution (i.e. use 
3,200,1 instead of 3,50,4) but there is still the chance you'll remove 
thousands of tiny spheres from the image if you render a big scene, so the 
resolution can have a dramatic effect on performance at very low
resolutions.

> >> inf = 100000.;
> >
> > This is nasty. Why is infinity not represented internally by the
> > floating 
> > point number infinity in Mathematica?
>
> Mathematica does not use machine double infinities, or bignum infinities
> for that matter. Generally when those are encountered in a computation
> e.g. with dedicated machine arithmetic, an exception is thrown and
> Mathematica attempts to work around it e.g. with software higher
> precision. 
>
> This is not to say there is no reason to have a machine double infinity
> in Mathematica. I can say, however, that putting one in would involve
> considerable work, and I think it would give but small improvement in
> speed or functionality.

Surely that is not the case here, where Compile'd code is intended to handle 
infinities often? Or does Compile already handle infinity as a 
machine-precision float?

> > What is the purpose of "With[{inf = inf}, ..]" here?
>
> This is to inject the evaluated form into the Compile. Else it is a
> nuisance to get that form, because Compile has the HoldAll attribute.

I see. :-)

> > Defer calculation of the normal. Fair enough but it is only done once
> > per 
> > pixel.
>
> It makes a small but measurable difference to speed. Helps a bit more
> than you indicate, because the original code uses Normalize inside
> Intersect, where it might be done as many times as lambda keeps
> decreasing for a given originating call (to Intersect, with the entire
> scene).

True. Hierarchical bounds checks mean that lambda cannot be decreased many 
times though. I should quantify exactly how often that occurs though.

Perhaps a more interesting solution would be to wrap the result in Hold[..]
to get laziness?

> >> In[22]:= Timing[ff512 = Main[9, 512, 4];]
> >> Out[22]= {1542.27, Null}
> >
> > That is orders of magnitude faster than my version but I am not sure
> > why. 
> > I suspect the main performance improvement comes from the use of packed
> > arrays but I haven't been able to reproduce it in my own code yet.
>
> Yes, packed arrays, which among other things avoids ALL exact arithmetic
> in places you do not want it. Also compiling RaySphere gives, by itself,
> a factor of two or more in overal speed gain.

I had already tried Compile but never got anywhere near that performance. I 
suspect your packed arrays and precalculated normalized vectors do the rest.

> >> At this point, it might make sense to use ParallelMap instead of Map,
> >> in Main.
> >
> > Replacing Map with ParallelMap slows it down, even with
> > Method -> "CoarsestGrained". How can I get a speedup from my 8 cores?!
> > :-)
> >
> > Many thanks,
>
> I only made the suggestion, without trying it, because I have no actual
> familiarity with ParallelMap. But one possibility: did you use
> DistributeDefinitions on all the functions underneath that Map? If not,
> that could certainly make it slower rather than faster.

I've managed to get rid of all the errors by calling DistributeDefinitions 
with the symbol names of all functions *and* the local "scene" variable
right before the ParallelMap. However, this still doesn't give any
performance improvement (and it only spawns 4 kernels for my 8 cores).

Might make a nice parallelism demo for Mathematica 7 if you can get it 
working...

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


  • Prev by Date: Re: Plot vs NMaximize
  • Next by Date: Re: Re: A 3D Plot Query
  • Previous by thread: Re: Mathematica 7 is now available
  • Next by thread: Re: Mathematica 7 is now available