我正在 Intellij Idea 中运行一些 CPU 密集型 Clojure 代码(我认为这并不重要——它似乎只是产生了一个进程)。根据 htop 和 top 的说法,它在我的笔记本电脑上使用了所有 4 个内核(嗯,2 + 超线程)。尽管我在代码中没有任何明确的并行性。
更详细一点:top 显示了一个 CPU 使用率约为 380% 的单个进程,而 htop 显示了一个“父”进程,然后是 4 个“子”进程,每个进程有 1/4 的时间和 100% 的 CPU。
这是正常的吗?或者这是否意味着我在某个地方遇到了一些非常错误的事情?该代码涉及许多惰性序列,但其核心修改了可变数据结构(可变的 - 不是 Clojure 数据结构 - 累积结果的哈希)。 我没有使用任何明确的并行性。
在 JCA/JCE(加密库)中可能花费了大量时间(我没有分析过) - 我在 CTR 模式下使用多个 AES 密码,每个密码都作为安全随机字节流(此处的代码),实现为惰性序列。也许这是并行化的?
更多随机想法:这可能与 IO 有关吗?我在一个加密的 SSD 上运行,这个程序正在处理来自磁盘的数据,所以进行了大量的读取。但是 htop 将系统时间显示为红色,而这些是绿色的。
抱歉问了这么模糊的问题。如果需要,我可以发布更多信息。这是 64 位 Linux (JDK 1.7.0_05) 上的 Clojure 1.4。正在执行的代码在这里,但它非常混乱(更抱歉)并且分布在各种文件中(大部分 CPU 时间都花在了nearest-in-dump
那里的代码中)。注意 - 请不要浪费时间尝试运行代码来重现,因为它期望预先存在的数据转储在磁盘上(不在 git 中)。
调试器在调试器中运行(谢谢,AM)显示四个线程(如果我正确理解调试器),但只有一个正在执行程序。它们被标记为终结器、主(程序)、引用处理程序和信号调度程序。Finalizer + ref handler 处于等待状态;信号调度程序没有可用的帧。我暂时认为这意味着并行性处于较低水平,也许在加密实现中?
啊哈,我认为它是并行 GC(Java 现在有一个并发收集器)。开始时,当实际进程暂停时,CPU 使用率会大幅上升(它会打印出一个常规的滴答声)。而且由于它正在处理大量数据,因此会生成许多短期对象(通过使用 -XX:+UseSerialGC 确认,这将 CPU 使用率降低到 100%)