On Nov 28, 2007 11:18 AM, Dan Weston &lt;<a href="mailto:westondan@imageworks.com">westondan@imageworks.com</a>&gt; wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Just out of curiosity...<br><br>&gt; --some getter functions<br>&gt; pVel !(_,vel,_) = vel<br>&gt; pPos !(pos,_,_) = pos<br>&gt; pMass !(!_,!_,!mass) = mass<br><br>What does the !(...) buy you? I thought tuples were already strict by
<br>default in patterns (you&#39;d need ~(...) to make them irrefutable), so<br>isn&#39;t the above equivalent to:<br><br>--some getter functions<br>pVel &nbsp;(_,vel,_) = vel<br>pPos &nbsp;(pos,_,_) = pos<br>pMass (!_,!_,!mass) = mass
<br></blockquote><div><br>Yes you are right. I did not need those extra ! in front of the tuples.&nbsp; <br>&nbsp;</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>And why in any case are the tuple components for pMass strict but for<br>pVel and pPos non-strict? Is is that mass is always used but position<br>and velocity are not?<br><div class="Ih2E3d"></div></blockquote><div><br>
Without all three components of the tuple in pMass being !&#39;d, I find a 2x slowdown. This include trying pMass (_,_,!mass), pMass(!_,_,!mass), and all other combinations.<br><br>Why that happens.. I do not know. pMass is only used where its argument (the planet tuple) was defined strict like below. I would expect p1 to be fully evaluated before pMass p1 is ever called. 
<br><br>offset_momentum (!p1,p2,p3,p4,p5) = ( pp1,p2,p3,p4,p5 ) where<br>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; pp1 = ( pPos p1,ppvel,pMass p1 ) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d"><br>Ryan Dickie wrote:<br>&gt; I sat down tonight and did tons of good learning (which was my goal).<br>&gt; Yes, the variable names in the unrolling is a little &quot;ugly&quot; but it helps<br>&gt; to read the C++ version for context. There are two for loops (advN is
<br>&gt; each inner one unrolled). the other function names match the C++<br>&gt; version. &nbsp;It was my goal to implement an unrolled version of that.<br>&gt;<br>&gt; Fortunately, my performance is excellent now. It is only 4x slower than
<br>&gt; the C++ version and 2x slower than the Haskell one listed (which uses<br>&gt; pointer trickery). I am sure there could be more done but I am at my<br>&gt; limit of comprehension. But if I may guess, I would say that any speed
<br>&gt; issues now are related to a lack of in place updating for variables and<br>&gt; structures.<br>&gt;<br>&gt; I&#39;d also like to thank everyone for their help so far. I have attached<br>&gt; my latest version.<br>
&gt;<br>&gt; --ryan<br>&gt;<br>&gt; On Nov 27, 2007 7:14 PM, Sterling Clover &lt; <a href="mailto:s.clover@gmail.com">s.clover@gmail.com</a><br></div><div><div></div><div class="Wj3C7c">&gt; &lt;mailto:<a href="mailto:s.clover@gmail.com">
s.clover@gmail.com</a>&gt;&gt; wrote:<br>&gt;<br>&gt; &nbsp; &nbsp; The first step would be profiling -- i.e. compiling with -prof -auto-<br>&gt; &nbsp; &nbsp; all to tag each function as a cost center, then running with +RTS -p<br>&gt; &nbsp; &nbsp; to generate a cost profile. The problem here is you&#39;ve got massive
<br>&gt; &nbsp; &nbsp; amounts of unrolling done already, so it&#39;s sort of hard to figure out<br>&gt; &nbsp; &nbsp; what&#39;s doing &nbsp;what, and the names you&#39;ve given the unrolled functions<br>&gt; &nbsp; &nbsp; are... less than helpful. (first rule of optimization: optimize
<br>&gt; &nbsp; &nbsp; later.) &nbsp;The use of tuples shouldn&#39;t be a problem per se in terms of<br>&gt; &nbsp; &nbsp; performance, but it really hurts readability to lack clear type<br>&gt; &nbsp; &nbsp; signatures and types. You&#39;d probably be better off constructing a
<br>&gt; &nbsp; &nbsp; vector data type as does the current Haskell entry -- and by forcing<br>&gt; &nbsp; &nbsp; it to be strict and unboxed (you have nearly no strictness<br>&gt; &nbsp; &nbsp; annotations I note -- and recall that $! only evaluates its argument
<br>&gt; &nbsp; &nbsp; to weak head normal form, which means that you&#39;re just checking if<br>&gt; &nbsp; &nbsp; the top-level constructor is _|_) you&#39;ll probably get better<br>&gt; &nbsp; &nbsp; performance to boot. In any case, declaring type aliases for the
<br>&gt; &nbsp; &nbsp; various units you&#39;re using would also help readability quite a bit.<br>&gt;<br>&gt; &nbsp; &nbsp; --S<br>&gt;<br>&gt; &nbsp; &nbsp; On Nov 27, 2007, at 5:41 PM, Ryan Dickie wrote:<br>&gt;<br>&gt; &nbsp; &nbsp; &nbsp;&gt; I thought it would be a nice exercise (and a good learning
<br>&gt; &nbsp; &nbsp; &nbsp;&gt; experience) to try and solve the nbody problem from the debian<br>&gt; &nbsp; &nbsp; &nbsp;&gt; language shootout. Unfortunately, my code sucks. There is a massive<br>&gt; &nbsp; &nbsp; &nbsp;&gt; space leak and performance is even worse. On the bright side, my
<br>&gt; &nbsp; &nbsp; &nbsp;&gt; implementation is purely functional. My twist: I manually unrolled<br>&gt; &nbsp; &nbsp; &nbsp;&gt; a few loops from the C++ version.<br>&gt; &nbsp; &nbsp; &nbsp;&gt;<br>&gt; &nbsp; &nbsp; &nbsp;&gt; I believe that most of my performance problems stem from my abuse
<br>&gt; &nbsp; &nbsp; &nbsp;&gt; of tuple. The bodies are passed as a tuple of planets, a planet is<br>&gt; &nbsp; &nbsp; &nbsp;&gt; a tuple of (position, velocity, mass) and the vectors position and<br>&gt; &nbsp; &nbsp; &nbsp;&gt; velocity are also tuples of type double. My lame justification for
<br>&gt; &nbsp; &nbsp; &nbsp;&gt; that is to make it nice and handy to pass data around.<br>&gt; &nbsp; &nbsp; &nbsp;&gt;<br>&gt; &nbsp; &nbsp; &nbsp;&gt; Any tips would be greatly appreciated.<br>&gt; &nbsp; &nbsp; &nbsp;&gt;<br>&gt; &nbsp; &nbsp; &nbsp;&gt; --ryan<br>&gt; &nbsp; &nbsp; &nbsp;&gt; &lt;nbody3.hs
&gt;<br>&gt; &nbsp; &nbsp; &nbsp;&gt; _______________________________________________<br>&gt; &nbsp; &nbsp; &nbsp;&gt; Haskell-Cafe mailing list<br></div></div>&gt; &nbsp; &nbsp; &nbsp;&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a> &lt;mailto:
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a>&gt;<br><div class="Ih2E3d">&gt; &nbsp; &nbsp; &nbsp;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe
</a><br>&gt;<br>&gt;<br>&gt;<br></div>&gt; ------------------------------------------------------------------------<br><div><div></div><div class="Wj3C7c">&gt;<br>&gt; _______________________________________________<br>&gt; Haskell-Cafe mailing list
<br>&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a>
<br><br><br></div></div></blockquote></div><br>