【问题标题】:How to control using CPU cores [Crystal]如何使用 CPU 内核进行控制 [Crystal]
【发布时间】:2016-09-11 11:21:16
【问题描述】:

我尝试在 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 64 位
  • 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?

【问题讨论】:

  • Crystal 程序中只能使用一个内核,其他内核中少量用于垃圾回收。但是,对于编译阶段,一切正常。在我看到严格的证据之前我不会相信这一点,最重要的是,你运行的程序以及你是如何运行它的。
  • @OlehPrypin 我使用命令“crystal run --release ”执行了程序。我会在几天内尝试将代码推送到我的 github 存储库中。
  • 一个好的第一步是先到crystal build,然后只测试完成的可执行文件。
  • 如果你在做crystal run ...,那么这会编译并运行你的程序。 LLVM 参与编译步骤,我很确定 LLVM 使用多个内核,所以这就是你的答案。仅运行 Crystal 代码的 Crystal 二进制文件目前仅使用一个内核。尝试crystal build,然后按照 Oleh 的建议执行生成的程序。
  • 我按照您的建议尝试了 2 步“水晶构建”和“执行生成的二进制文件”。然而同样的现象也出现了。我在其他 PC 和操作系统(Linux mint 17 64 位)上也看到了相同的操作。我的水晶代码可能有问题。稍后我会尝试将代码推送到 github 中。

标签: crystal-lang


【解决方案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 个系统线程。

【讨论】:

    猜你喜欢
    • 2022-09-18
    • 2017-01-25
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2022-08-15
    • 2020-07-21
    • 1970-01-01
    • 2019-01-06
    相关资源
    最近更新 更多