0

我尝试在 Ruby 和 Crystal 上运行相同的程序。在程序中,没有控制线程的代码。

至于 Ruby,只使用了 1 个核心,通过程序使用率为 100%,如下图所示 在此处输入图像描述 ,时间命令的报告是

真正的 5m21.168s
用户 5m20.784s
系统 0m0.296s

水晶方面,所有核心都被使用,CPU 使用率在 170% 左右。 在此处输入图像描述 时间报告是

真正的 1m51.299s
用户 2m25.876s
系统 0m48.380s

这是否意味着水晶的编译器做了特定的工作来构建一个合理使用内核的二进制文件?如果是这样,有没有办法创建一个只在 Ruby 等 1 个核心上运行的二进制文件?

(健康)状况

  • CPU:英特尔酷睿 i7 6700
  • 操作系统:Ubuntu 16.04 64bit
  • Ruby 版本:2.4.0-preview2
  • 水晶版:0.18.7 / 0.19.1

------------ 2016 年 9 月 13 日添加了以下说明 --------------

代码

我通过以下步骤执行了代码。

$ crystal build examples/wave_form_standalone.cr
$ ./wave_form_standalone > /dev/null

顺便说一句,我检查了以下简单代码以查明原因。

j = 0
10000000000.times do |i|
  j += i
  j -= 1
end

此代码使用 1 个核心,并且 100% 正确使用。然而,许多内核都与上述 github 的水晶代码一起使用。所以,这似乎取决于代码。是否存在 GC 频繁运行导致主程序无法有效使用 CPU 的可能性?

4

1 回答 1

1

您可以通过将 Crystal 限制为一个 GC 标记线程来获得所需的行为:

time GC_MARKERS=1 ./wave_form_standalone > /dev/null
GC_MARKERS=1 ./wave_form_standalone > /dev/null  73,12s user 1,47s system 98% cpu 1:15,49 total

GC_MARKERS环境变量记录在 Boehm GC 的README.environment

GC_MARKERS=<n>– 仅当使用 . 编译时PARALLEL_MARK。设置标记线程数。这通常设置为处理器的数量。调整GC_MARKERS比更安全GC_NPROCS,因为GC_MARKERS对锁的实现没有影响。

文档不是很准确:它实际上每个逻辑核心启动一个线程,所以在 Core i7-5557U(2 个核心,4 个线程)上,我正在测试它默认启动 4 个系统线程。

于 2018-07-18T00:59:12.227 回答