2

Clojure でプログラムのベンチマークを書いています。n同時にキャッシュにアクセスするスレッドがあります。各スレッドはキャッシュx時間にアクセスします。各リクエストは、ファイル内に記録する必要があります。

この目的のために、書き込み先のファイルへのパスを保持するエージェントを作成しました。書きたいときは send-off、ファイルに書き込み、単にパスを返す関数を書きます。このようにして、私のファイル書き込みは競合状態から解放されます。

エージェントなしでコードを実行すると、数ミリ秒で終了しました。エージェントを使用すると、コードの実行が非常に遅くなるたびに、各スレッドにエージェントに送信するように依頼します。私は議事録を話している。

(defn load-cache-only [usercount cache-size]
  "Test requesting from the cache only."
  ; Create the file to write the benchmark results to.
  (def sink "benchmarks/results/load-cache-only.txt")
  (let [data-agent (agent sink)
        ; Data for our backing store generated at runtime.
        store-data (into {} (map vector (map (comp keyword str)
                                             (repeat "item") 
                                             (range 1 cache-size)) 
                                        (range 1 cache-size)))
        cache      (create-full-cache cache-size store-data)]
    (barrier/run-with-barrier (fn [] (load-cache-only-work cache store-data data-agent)) usercount)))

(defn load-cache-only-work [cache store-data data-agent]
  "For use with 'load-cache-only'. Requests each item in the cache one.
   We time how long it takes for each request to be handled."
  (let [cache-size  (count store-data)
        foreachitem (fn [cache-item]
                      (let [before  (System/nanoTime)
                            result  (cache/retrieve cache cache-item)
                            after   (System/nanoTime)
                            diff_ms ((comp str float) (/ (- after before) 1000))]
                        ;(send-off data-agent (fn [filepath] 
                                           ;(file/insert-record filepath cache-size diff_ms)
                                           ;filepath))
                        ))]
    (doall (map foreachitem (keys store-data)))))

(barrier/run-with-barrier)コードは単純に複数のスレッドを生成しusercount、それらを同時に開始します (atom を使用)。私が渡す関数は、各スレッドの本体です。

store-data本文は、キーと値のリストであるという名前のリストに単純にマップされます (例: {:a 1 :b 2}。現在、コード内のこのリストの長さは 10 です。ユーザーの数も 10 です。

ご覧のとおり、エージェント見送りのコードはコメントアウトされています。これにより、コードが正常に実行されます。ただし、送信を有効にすると、ファイルに書き込まなくても実行時間が遅すぎます。

編集:

彼がエージェントに送信する前に、各スレッドにドットを印刷しました。ドットは見送りがない場合と同じくらい速く表示されます。したがって、最終的には何かがブロックする必要があります。

私は何か間違ったことをしていますか?

4

1 に答える 1

5

(shutdown-agents)JVM を適切な時間内に終了させたい場合は、エージェントへの送信が完了したら呼び出す必要があります。

根本的な問題は、エージェントをシャットダウンしないと、そのスレッドプールをサポートするスレッドがシャットダウンされず、JVM が終了できないことです。他に何も実行されていない場合にプールをシャットダウンするタイムアウトがありますが、かなり時間がかかります。アクションの作成が完了したらすぐに呼び出すshutdown-agentsと、この問題が解決されます。

于 2014-05-02T14:02:28.953 に答える