pmap
함수에 대한 문서는 웹에서 XML 피드 모음을 가져 오는 것과 같이 얼마나 효율적인지 궁금합니다. 나는 얼마나 많은 동시 페치 연산 pmap이 생성되고 최대 값이 될지 전혀 모른다. 당신이 소스를 선택하면Clojure의 pmap 함수가 URL 가져 오기 작업을 위해 얼마나 많은 스레드를 생성합니까?
답변
당신은 참조하십시오
> (use 'clojure.repl)
> (source pmap)
(defn pmap
"Like map, except f is applied in parallel. Semi-lazy in that the
parallel computation stays ahead of the consumption, but doesn't
realize the entire result unless required. Only useful for
computationally intensive functions where the time of f dominates
the coordination overhead."
{:added "1.0"}
([f coll]
(let [n (+ 2 (.. Runtime getRuntime availableProcessors))
rets (map #(future (f %)) coll)
step (fn step [[x & xs :as vs] fs]
(lazy-seq
(if-let [s (seq fs)]
(cons (deref x) (step xs (rest s)))
(map deref vs))))]
(step rets (drop n rets))))
([f coll & colls]
(let [step (fn step [cs]
(lazy-seq
(let [ss (map seq cs)]
(when (every? identity ss)
(cons (map first ss) (step (map rest ss)))))))]
(pmap #(apply f %) (step (cons coll colls))))))
(+ 2 (.. Runtime getRuntime availableProcessors))
가 큰 단서입니다. pmap은 첫 번째 (+ 2 processors)
조각을 잡고 future
을 통해 비동기 적으로 실행합니다. 따라서 코어가 2 개있는 경우 한 번에 4 조각을 시작하여 조금 앞선 상태로 유지하려고 시도하지만 최대 값은 2 + n이어야합니다.
future
은 궁극적으로 제한되지 않은 수의 스레드를 지원하는 에이전트 I/O 스레드 풀을 사용합니다. 그것은 쓰레기가 쓰레기로 쓰인대로 성장할 것이고 쓰레드가 사용되지 않는다면 줄어들 것입니다.
건물, 여기에 상황에 내 제안이다 :
(doall
(map
#(future (my-web-fetch-function %))
list-of-xml-feeds-to-fetch))
이론적 근거 :
이- 당신은 기내 작업의 많은 부분 당신이 할 수 원하는 대부분의 경우 네트워크 IO에서 차단됩니다.
- Future는 스레드 풀에서 처리되도록 각 요청에 대해 비동기 작업을 시작합니다. Clojure가이를 지능적으로 처리하도록 할 수 있습니다.
- 지도상의 doall은 전체 시퀀스 (예 : 모든 요청 실행)를 강제로 평가합니다.
- 주 스레드는 바로 미래를 역 참조 시작할 수 있으며, 각각의 결과를 다시
긴 응답을 작성하는 시간이 올 따라서 진전을 계속할 수 있지만, clojure.contrib HTTP 에이전트가있다있는 각각의 get/post 요청을 자체 에이전트로 작성합니다. 따라서 수천 건의 요청을 처리 할 수 있으며 결과가 나오면 모두 병렬로 실행하여 완료 할 수 있습니다.
pmap의 작동을 보면 한 번에 32 개의 스레드가있는 것으로 보입니다. 문제는지도가 계산에 앞서 32 씩 진행되고 미래가 스스로 시작된다는 것입니다. (샘플) (defn samplef [n] (println "starting " n) (Thread/sleep 10000) n) (def result (pmap samplef (range 0 100)))
; 33 초를 기다릴 때 10 초를 기다린 다음 32 장을보고; 한 번에 32 개의 동시 스레드를 수행 중이라는 분을 인쇄합니다. ; 나에게 이것은 완벽하지 않다. ; SALUDOS Felipe
많은 웹 호출을 처리하고 응답을 처리 할 때'pmap'이 완벽하게 괜찮습니까? 거기에 어떤주의 사항이 있습니까? – dan
내가 틀렸을 수도 있지만 문제는 아마도 n + 2 스레드가 웹 응답을 기다리는 것을 차단할 것입니다. 따라서 최대 처리량에 대한 충분한 요청을 얻을 수 없습니다. pmap은 실제로 CPU 바인딩 작업 부하를위한 것입니다. 이런 일이 발생하면 미래에 각 요청 통화를 래핑 할 수 있으며 모두 즉시 중단됩니다. – mikera
그럼 동시성에 대한 짧은 대답은 없습니다. :) 필자는 pmap이이 사용 사례에 실제로 이상적이지 않다고 말하고 싶습니다. 소스의 모든 *을 병렬로 기다리기를 정말로 원합니다 - pmap은 위의 경우에서 5 번째 시작을 지연시킵니다.Pmap의 게으른 행동이 좋은 경우라면, 모든 소스를 다 통과하기를 원하지 않는다면 말이다. 대신에 당신의 물건이 소스를 맵핑하고 미래를 사용하여 각 요청을하도록 유혹받을 것입니다. –