Your check-concurrent2 is a much better way to use parallelism in your program -- create a few threads, each of which does a lot of work.
I haven't analyzed the values you are computing in detail, but note that your program still has lots of inter-thread 'communication' because of the use of a common atom in your main-function. If you can get the correct final answer by having each thread calculate independent values, or collections of values, and then somehow combining them together when they are all finished with a bit of quick-running sequential code, that might give you even better parallel speedup than check-concurrent2. The use of asterisks at beginning and end of a symbol name is traditionally used on Clojure (and Common Lisp, from whence this tradition came) if the var is dynamically bound, meaning different threads typically do things like (binding [*dynamic-var* value-to-use-in-my-thread] <code here>). There is no need for that in your program, and leaving off the asterisks (or "earmuffs") is common practice. For the explanation of the 1-minute delay, see the end of the last example on ClojureDocs for the future function: http://clojuredocs.org/clojure_core/clojure.core/future Andy On Thu, Apr 10, 2014 at 4:35 PM, Cecil Westerhof <cldwester...@gmail.com>wrote: > 2014-04-10 16:45 GMT+02:00 Andy Fingerhut <andy.finger...@gmail.com>: > > Forcing small bits of computation to be done in parallel using the tools >> Clojure and the JVM have at hand, e.g. pmap, future, etc., which rely on >> creating JVM Thread objects, tends to slow things down rather than speed >> things up, because the extra overhead of creating threads and waiting for >> them to finish is higher than the cost of sequentially doing the small bits >> of computation. >> >> If you want to force parallelism in your example anyway, to compare the >> most-likely-slower-performance against what you have now, you can try this: >> >> (let [val (Math/sqrt i) >> a1 (future (Math/pow val 2)) >> a2 (future (* val val)) >> diff (Math/abs (- @a1 @a2))] >> > > The first form of concurrency was very bad indeed. I attached the script > I made. (With the first form of concurrency disabled.) The sequential > version takes between 1:52 and 1:56 with 18% CPU. > > The first form of concurrency took 2 hours and 45 minutes with 26% CPU. > That is about 87 times as long, so very bad indeed. A future seems to be > very expensive. > > The second form of concurrency takes around 31 seconds with 57% CPU. So > about 3.7 times as fast. So that is a good improvement. The output is > not complete the same, but that is not important in this case. > > By the way: is this the right way to write Clojure code? Especially: are > the names max-diff and max-factor correct, or should the names be called > different? For example: *max-fiff*. > > I call the script with: > date +%T ; clojure ~/Clojure/check-power.clj ; date +%T > > This gives: > 00:52:10 > 00:52:11: Start sequential > 00:52:11: Different for 838 (1.136868e-13, 1.356645e-16) > 00:52:11: Different for 3352 (4.547474e-13, 1.356645e-16) > 00:52:11: Different for 5343 (9.094947e-13, 1.702217e-16) > 00:52:11: Different for 9470 (1.818989e-12, 1.920791e-16) > 00:52:11: Different for 19922 (3.637979e-12, 1.826111e-16) > 00:52:11: Different for 33757 (7.275958e-12, 2.155392e-16) > 00:52:11: Different for 65830 (1.455192e-11, 2.210529e-16) > 00:52:11: Different for 132323 (2.910383e-11, 2.199454e-16) > 00:52:11: Different for 263320 (5.820766e-11, 2.210529e-16) > 00:52:12: Different for 524523 (1.164153e-10, 2.219451e-16) > 00:52:12: Different for 1052879 (2.328306e-10, 2.211371e-16) > 00:52:12: Different for 2097255 (4.656613e-10, 2.220337e-16) > 00:52:12: Different for 4194573 (9.313226e-10, 2.220304e-16) > 00:52:12: Different for 8389020 (1.862645e-09, 2.220337e-16) > 00:52:13: Different for 16777781 (3.725290e-09, 2.220371e-16) > 00:52:16: Different for 33554486 (7.450581e-09, 2.220442e-16) > 00:52:19: Different for 67110098 (1.490116e-08, 2.220405e-16) > 00:52:27: Different for 134217944 (2.980232e-08, 2.220442e-16) > 00:52:42: Different for 268436271 (5.960464e-08, 2.220439e-16) > 00:53:13: Different for 536871776 (1.192093e-07, 2.220442e-16) > 00:54:06: Stop, max-factor: 2.220442e-16 > > > 00:54:06: Start concurrent2 > 00:54:06: Different for 838 (1.136868e-13, 1.356645e-16) > 00:54:06: Different for 5343 (9.094947e-13, 1.702217e-16) > 00:54:06: Different for 3674 (4.547474e-13, 1.237745e-16) > 00:54:06: Different for 10925 (1.818989e-12, 1.664979e-16) > 00:54:06: Different for 21372 (3.637979e-12, 1.702217e-16) > 00:54:06: Different for 20571 (3.637979e-12, 1.768499e-16) > 00:54:06: Different for 19922 (3.637979e-12, 1.826111e-16) > 00:54:06: Different for 33757 (7.275958e-12, 2.155392e-16) > 00:54:06: Different for 70012 (1.455192e-11, 2.078489e-16) > 00:54:06: Different for 135028 (2.910383e-11, 2.155392e-16) > 00:54:06: Different for 263320 (5.820766e-11, 2.210529e-16) > 00:54:06: Different for 529292 (1.164153e-10, 2.199454e-16) > 00:54:06: Different for 1053280 (2.328306e-10, 2.210529e-16) > 00:54:06: Different for 2098092 (4.656613e-10, 2.219451e-16) > 00:54:06: Different for 4211516 (9.313226e-10, 2.211371e-16) > 00:54:06: Different for 4194573 (9.313226e-10, 2.220304e-16) > 00:54:06: Different for 8389473 (1.862645e-09, 2.220217e-16) > 00:54:07: Different for 16777781 (3.725290e-09, 2.220371e-16) > 00:54:07: Different for 33555125 (7.450581e-09, 2.220400e-16) > 00:54:08: Different for 67115849 (1.490116e-08, 2.220215e-16) > 00:54:10: Different for 134218985 (2.980232e-08, 2.220425e-16) > 00:54:14: Different for 268441753 (5.960464e-08, 2.220394e-16) > 00:54:23: Different for 536872413 (1.192093e-07, 2.220440e-16) > 00:54:37: Stop, max-factor: 2.220440e-16 > 00:55:37 > > One thing I do not understand, between finishing (check-concurrent2) and > getting back to the shell there is one minute. When calling only > (check-sequential) the script returns immediately back to the shell. Why > is this? > > > On Thu, Apr 10, 2014 at 7:35 AM, Cecil Westerhof > <cldwester...@gmail.com>wrote: >> >>> I have the following in my code: >>> (let [val (Math/sqrt i) >>> diff (Math/abs (- (Math/pow val 2) (* val val)))] >>> >>> I expect that calculating the difference is the most expensive part of >>> my code. I understood that Clojure is very good in parallellisation. How >>> would I let (Math/pow val 2) and (* val val) be calculated in parallel? >>> >> > -- > Cecil Westerhof > > -- > 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 > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.