On Jul 2, 7:13 pm, Nicolas Oury <nicolas.o...@gmail.com> wrote:
> Hello,
> I just have a look at your code. I was wondering why reflect.Array/getDouble
> was faster than aget?

(aget arrayname) actually makes a call to java.lang.reflect.Array/get
which looks at the type of data in the array and then does the right
thing. Calling  java.lang.reflect.Array/getDouble directly saves the
time for type resolving (I guess) and gives me a 30% speedup.

> And I realized than you create arrays of objects and not array of doubles.
>
> Have you tried to replace make-array by double-array?

I'm using an equivalent of double-array:

user> (make-array Double/TYPE 5)
#<double[] [...@7f14671e>
user> (double-array 5)
#<double[] [...@60d8edf8>
user>

> You can also try to replace the arithmetic by unchecked arithmetic. (Is it
> correct from the point of view of the semantic of the VM you are
> implementing?).

I didn't get to that yet because my profiling shows that the amount of
time spent getting values from an array (even when using getDouble)
surpasses by far the time spent in any other operation. Of course, my
understanding of the JVM profiler logs may be wrong.

> Can you try to check in your profiling whether the function you generate get
> compiled or not?

Looks like my function did not get compiled, here is the java -Xprof
log: http://paste.org/8811 On line 10 you can se the method
loneclojurian.ovm2$eval__3920$fn__3922.invoke. But you can see that
only 0.5% of time is spent in that function. Scroll down to line 44
and you will see the real time wasters:

54.9%     0  +  2413    java.lang.reflect.Array.getDouble
21.0%     0  +   924    java.lang.reflect.Array.setDouble

Looks like the JIT compiler decided it would be a waste of time to
compile my function and I agree.  :)

> What function are you running at the top level? Is that a loop where you run
> multiple times the same program?

This is the contents of benchmark.clj:

(require 'loneclojurian.ovm2)

(in-ns 'loneclojurian.ovm2)
(def machine (init-ovm "/path/to/bin1.obf"))
(defn one-run [] (machine) [(aget output-ports 0)
                            (aget output-ports 1)
                            (aget output-ports 2)
                            (aget output-ports 3)
                            (aget output-ports 4)])

(time (dotimes [_ 200000] (one-run)))

So, init-ovm returns a function that executes the program, then I
define the one-run function that mimics the "real" usage of the VM:
execute the program once and then get the values of the first 5 output
ports (this is all related to problem 1).

So, I think the problem is that this approach of emulating computer
memory is quite resource hungry. Either a way needs to be found to
make these gets and sets really cheap or I need to rethink the
problem.

--
IgorR
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to