我尝试使用clojure pantomime
库从大量tif
文档(以及其他文档)中提取/ ocr文本。
我的计划是使用pmap在一系列输入数据(来自postgres数据库)上应用映射,然后使用tika / tesseract OCR输出更新同一个postgres数据库。这一直工作正常,但是我注意到htop中很多核心有时都处于空闲状态。
无论如何都要调和这个,我可以采取哪些步骤来确定为什么这可能会阻塞某个地方?所有处理都在单个tif文件上进行,每个线程完全互斥。
其他信息:
htop
正在等待future
?怎么分辨到哪里? 任何提示都表示赞赏,谢谢。代码在下面添加。
deref
答案 0 :(得分:3)
pmap
在批量(+ 2个核心)上并行运行map函数,但保留了排序。这意味着如果您有8个核心,则将处理一批10个项目,但只有在所有10个项目完成后才会启动新批次。
您可以创建自己的代码,使用future
,delay
和deref
的组合,这将是一个很好的学术练习。之后,您可以抛弃您的代码并开始使用claypoole库,该库具有一组涵盖future
的大部分用法的抽象。
对于这种特定情况,请使用无序的pmap
或pfor
实施(upmap
和upfor
),这与pmap
完全相同没有订购;只要批次中的任何一个项目完成,就会选择新项目。
在IO是主要瓶颈的情况下,或处理时间因工作项目而异的情况,这是并行map
或for
操作的最佳方式。
当然,您应该注意不要依赖任何类型的返回值排序。
(require '[com.climate.claypoole :as cp])
(cp/upmap (cp/ncpus)
#(try
(update-a-row %)
(catch Exception e (t/error (.getNextException e)))
)
fetch-all-batch )
答案 1 :(得分:1)
前段时间我遇到过类似的问题。我想你和我一样做了相同的假设:
pmap并行调用f。但这并不意味着工作是平等分享的。如你所说,有些需要3秒,而其他需要90秒。在3秒内完成的线程不会要求其他人分享剩下要完成的工作。所以完成的线程只是等待直到最后一个完成。
你没有准确描述你的数据是怎样的,但我会假设你正在使用某种延迟序列,这对并行处理是不利的。如果您的进程是CPU限制的,并且您可以将整个输入保存在内存中,那么更喜欢使用clojure.core.reducers('map','filter'和特别'fold')来使用惰性映射,过滤器和其他
在我的情况下,这些提示将处理时间从34秒减少到仅仅8秒。希望它有所帮助