Project

General

Profile

Actions

Feature #14723

open

[WIP] sleepy GC

Added by normalperson (Eric Wong) over 6 years ago. Updated over 6 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:86755]

Description

The idea is to use "idle time" when process is otherwise sleeping
and using no CPU time to perform GC. It makes sense because real
world traffic sees idle time due to network latency and waiting
for user input.

Right now, it's Linux-only. Future patches will affect other sleeping
functions:

IO.select, Kernel#sleep, Thread#join, Process.waitpid, etc...

I don't know if this patch can be implemented for win32, right
now it's just dummy functions and that will be somebody elses
job. But all pthreads platforms should eventually benefit.

Before this patch, the entropy-dependent script below takes 95MB
consistently on my system. Now, depending on the amount of
entropy on my system, it takes anywhere from 43MB to 75MB.

I'm using /dev/urandom to simulate real-world network latency
variations. There is no improvement when using /dev/zero
because the process is never idle.

require 'net/http'
require 'digest/md5'
Thread.abort_on_exception = true
s = TCPServer.new('127.0.0.1', 0)
len = 1024 * 1024 * 1024
th = Thread.new do
c = s.accept
c.readpartial(16384)
c.write("HTTP/1.0 200 OK\r\nContent-Length: #{len}\r\n\r\n")
IO.copy_stream('/dev/urandom', c, len)
c.close
end

addr = s.addr
Net::HTTP.start(addr[3], addr[1]) do |http|
http.request_get('/') do |res|
dig = Digest::MD5.new
res.read_body { |buf|
dig.update(buf)
}
puts dig.hexdigest
end
end

The above script is also dependent on net/protocol using
read_nonblock. Ordinary IO objects will need IO#nonblock=true
to see benefits (because they never hit rb_wait_for_single_fd)

  • gc.c (rb_gc_inprogress): new function
    (rb_gc_step): ditto
  • internal.h: declare prototypes for new gc.c functions
  • thread_pthread.c (gvl_contended_p): new function
  • thread_win32.c (gvl_contended_p): ditto (dummy)
  • thread.c (rb_wait_for_single_fd w/ ppoll):
    use new functions to perform GC while GVL is uncontended
    and GC is lazy sweeping or incremental marking
    [ruby-core:86265]

2 part patch broken out
https://80x24.org/spew/20180429035007.6499-2-e@80x24.org/raw
https://80x24.org/spew/20180429035007.6499-3-e@80x24.org/raw

Also on my "sleepy-gc" git branch @ git://80x24.org/ruby.git

Files

sleepy-gc-wip-v1.diff (5.37 KB) sleepy-gc-wip-v1.diff normalperson (Eric Wong), 04/29/2018 03:57 AM
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0