0

I tried to run the same program on both Ruby and Crystal. In the program, there is no code which controls threads.

As for Ruby, Only 1 core is used and the usage is 100% through the program as following screen shot indicates enter image description here and the report of time command is

real    5m21.168s
user    5m20.784s
sys 0m0.296s

As for crystal, all cores are used and the usage of CPU about 170%. enter image description here and time report is

real    1m51.299s
user    2m25.876s
sys 0m48.380s

Does this mean that the compiler of crystal does specific work to build a binary which uses cores reasonably? If so, is there any way to create a binary which runs on only 1 core like Ruby?

condition

  • CPU: Intel core i7 6700
  • OS: Ubuntu 16.04 64bit
  • Ruby version: 2.4.0-preview2
  • Crystal version: 0.18.7 / 0.19.1

----------- added following description on 13th/Sep 2016 --------------

code

I executed the code with following steps.

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

By the way, I checked with following simple code in order to isolate the cause.

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

This code uses 1 core and the usage 100% correctly. However many cores are used with above crystal code of github. So, this seems to depend on the code. Is there the possibility that GC runs frequently and main program can't use CPU efficiently?

elgoog
  • 77
  • 5
  • 2
    Only one core should be used in Crystal programs, and a small amount in other cores for garbage collection. For the compilation stage, though, anything goes. I will not believe this until I see rigorous proof, most importantly, the program you ran and how you ran it. – Oleh Prypin Sep 11 '16 at 11:33
  • @OlehPrypin I executed the program with the command "crystal run --release ". I will try to push the code into my github repository within a few days. – elgoog Sep 11 '16 at 11:58
  • A good first step would be to `crystal build` first and then test only the finished executable. – Oleh Prypin Sep 11 '16 at 12:05
  • 1
    If you are doing `crystal run ...` then this compiles and runs your program. LLVM is involved in the compilation step, and I'm pretty sure LLVM uses multiple cores, so this is your answer. Crystal binaries that only run Crystal code only use one core for now. Try `crystal build` and then execute the generated program, as Oleh recommends. – asterite Sep 11 '16 at 12:19
  • I tried with 2 steps 'crystal build' and 'execute the produced binary' as you recommend. However the same phenomenon appeared. I saw the same operation on other PC and OS(Linux mint 17 64bit), too. My crystal code may have issues. I will try to push the code into github later. – elgoog Sep 11 '16 at 15:42
  • @asterite @OlehPrypin ` I added some information to the description and push the code into github. I also saw this phenomenon with Crystal 0.19.1. This seems to depends on the code. Is there the possibility that GC runs frequently and main program can't use CPU efficiently? – elgoog Sep 13 '16 at 11:16
  • Yes the GC spawns its own threads and does some work there. You can pin your exectuable to a single core with the `taskset` command, `taskset -c 0 ./wave_form_standalone >/dev/null`. – Jonne Haß Oct 19 '16 at 18:29

1 Answers1

1

You can get the desired behavior by limiting Crystal to one GC marker thread:

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

The GC_MARKERS environment variable is documented in the Boehm GC's README.environment:

GC_MARKERS=<n> – Only if compiled with PARALLEL_MARK. Set the number of marker threads. This is normally set to the number of processors. It is safer to adjust GC_MARKERS than GC_NPROCS, since GC_MARKERS has no impact on the lock implementation.

The documentation isn't quite accurate: It actually starts one thread per logical core, so on the Core i7-5557U (2 cores, 4 threads) I'm testing on it starts 4 system threads by default.

felixbuenemann
  • 579
  • 3
  • 18