当中止的线程数也增加时,为什么运行时计数会增加?

时间:2011-11-15 14:49:49

标签: transactions clojure

我问这个问题,找出我的运行时间数增加的原因。

我有一个简单的程序,它有一个对数字的引用向量和一堆线程同时试图写入向量中的一个数字。

通过修改向量的大小(在程序中称为直方图),我可以减少中止事务的数量,因为写入集对于较大的向量大小不会发生冲突。该程序中的大小称为“histsize”。

但是,当我减少中止事务的数量时,运行时会变为UP!在我的系统上,当我将中止事务的数量从2500减少到300时,运行时间从460毫秒上升到620毫秒。显然,还有其他的东西在发挥,但我似乎无法弄清楚它是什么。

这对我来说毫无意义。这是代码......谁能告诉我发生了什么?

(def histsize 5000)
(def histogram (vec (take histsize (repeatedly #(ref 0)))))
(def abort-counter (atom 0))

(defn inc_alter []
  (loop [counter 10000]
     (if (zero? counter)
        nil
     (do
       (dosync
         (try
           (let [index (mod counter histsize)]
             (ref-set (histogram index) (inc @(histogram index))))
           (catch Throwable t 
             (do
               (swap! abort-counter inc) 
               (throw t)))))
       (recur (dec counter))))))

(defn run-histo []
  (let [threads (for [x (range 0 20)] (Thread. #(inc_alter)))]
    (do
      (time
        (do (doall (map #(.start %) threads))
            (doall (map #(.join %) threads))))
      (println "total aborts: " @abort-counter) )))

(run-histo)

2 个答案:

答案 0 :(得分:2)

也许这只是JVM运行时优化的问题。第一次运行可能需要更长时间,但尝试连续运行?我将histogram向量的大小从5000增加到50000,连续10次运行得到了这个结果:

; 5000
("Elapsed time: 1221.597 msecs" total aborts:  203
 "Elapsed time: 466.733 msecs" total aborts:  64
 "Elapsed time: 484.87 msecs" total aborts:  127
 "Elapsed time: 730.735 msecs" total aborts:  127
 "Elapsed time: 461.475 msecs" total aborts:  97
 "Elapsed time: 488.735 msecs" total aborts:  178
 "Elapsed time: 484.342 msecs" total aborts:  42
 "Elapsed time: 447.577 msecs" total aborts:  96
 "Elapsed time: 478.22 msecs" total aborts:  178
 "Elapsed time: 402.598 msecs" total aborts: 125
 nil nil nil nil nil nil nil nil nil nil)


; 50000
("Elapsed time: 21.374 msecs" total aborts:  20
 "Elapsed time: 48.55 msecs" total aborts:  20
 "Elapsed time: 16.818 msecs" total aborts:  20
 "Elapsed time: 13.407 msecs" total aborts:  20
 "Elapsed time: 14.546 msecs" total aborts:  20
 "Elapsed time: 16.687 msecs" total aborts:  20
 "Elapsed time: 12.22 msecs" total aborts:  20
 "Elapsed time: 13.491 msecs" total aborts:  20
 "Elapsed time: 11.616 msecs" total aborts:  20
 "Elapsed time: 11.896 msecs" total aborts:  20
 nil nil nil nil nil nil nil nil nil nil)

修改后的run-histo

(defn run-histo []
  (for [x (range 10)]  
   (let [threads (for [x (range 0 20)] (Thread. #(inc_alter)))]
     (do
       (reset! abort-counter 0)
       (time
        (do (doall (map #(.start %) threads))
            (doall (map #(.join %) threads))))
       (println "total aborts: " @abort-counter) ))))

这如何在您的机器上运行?

答案 1 :(得分:0)

当你的中止次数较少时,线程将运行更多“循环”,因此需要更多时间才能完成,即它们将处理更多数量的“计数器”。然而当由于catch块中的throw而导致更多中止时,线程将被中止,因此线程的退出率将更高,因此它们将处理更少的“计数器”并花费更少的时间