Clojure(或 JCE、JVM,或...?)会自动引入并行性吗?

问题描述 投票:0回答:1

我正在 Intellij Idea 中运行一些 CPU 密集型 Clojure 代码(我认为这并不重要 - 它似乎只是生成一个进程)。根据 htop 和 top,它在我的笔记本电脑上使用了全部 4 个核心(好吧,2 个 + 超线程)。尽管我在代码中没有任何明确的并行性,但还是如此。

更详细一点:top 显示了一个大约 380% CPU 使用率的单个进程,而 htop 显示了一个“父”进程,然后是 4 个“子”进程,每个进程占用 1/4 的时间和大约 100% CPU。

这正常吗?或者这是否意味着我在某个地方出了什么问题?该代码涉及许多惰性序列,但其核心修改了可变数据结构(可变的 - 不是 Clojure 数据结构 - 累积结果的哈希)。 我没有使用任何显式并行性。

很可能(我没有分析)花费在 JCA/JCE(加密库)上 - 我在 CTR 模式下使用多个 AES 密码,每个密码都是安全随机字节流(此处为代码),作为惰性序列实现。也许这是并行的?

更多随机想法:这可能与 IO 有关吗?我在加密的 SSD 上运行,该程序正在处理磁盘中的数据,因此需要进行大量读取。但是 htop 将系统时间显示为红色,而这些是绿色的。

抱歉问了这么模糊的问题。如果需要,我可以发布更多信息。这是 64 位 Linux (JDK 1.7.0_05) 上的 Clojure 1.4。正在执行的代码位于here,但它非常混乱(更多抱歉)并且分布在各个文件中(大多数 CPU 时间都花在代码中的

nearest-in-dump
中)。注意 - 请不要浪费时间尝试运行代码来重现,因为它期望预先存在的数据转储位于磁盘上(不在 git 中)。

调试器 在调试器中运行(谢谢,A-M)显示四个线程(如果我正确理解调试器的话),但只有一个正在执行程序。它们被标记为终结器、主程序(程序)、引用处理程序和信号调度程序。 Finalizer + ref handler 处于等待状态;信号调度程序没有可用的帧。我初步认为这意味着并行性处于较低水平,也许在加密实现中?

啊哈我认为是并行GC(Java现在有并发收集器)。开始时,当实际进程暂停时,CPU 使用率会大幅上升(它会打印出常规的刻度)。由于它会搅动大量数据,因此会生成大量短期对象(通过使用 -XX:+UseSerialGC 进行确认,这会将 CPU 使用率降低到 100%)

clojure parallel-processing jvm jce
1个回答
4
投票

好吧,我觉得发布这个有点愚蠢,因为它现在看起来很明显,但它似乎是并行 GC。我正在处理大量数据(从 SSD 中吸收数据)并生成大量短暂的对象。而且JVM似乎有并行GC。请参阅http://blog.ragozin.info/2011/12/garbage-collection-in-hotspot-jvm.html 这也可能是一个问题的征兆 -

java GC 发生了什么? PermGen 空间已满?

- 我明天将进行调查(我没有提到它 - 虽然回想起来我应该有 - 但这是内存不足的边缘)。

更新

:使用 -XX:+UseSerialGC 运行可将总 CPU 使用率降低至 100%(即 1 个核心)。但我并不是说上面的两种解释是排他性的,只是说通过更好的配置和/或代码我可以减少 GC 的数量。

© www.soinside.com 2019 - 2024. All rights reserved.