faster Thread.exclusive

J

Joel VanderWerf

Ruby folks,

The following implementation of Thread.exclusive (called
Thread.my_exclusive) seems to gain a bit on the thread.rb implementation:

user system total real
warmup 0.300000 0.000000 0.300000 ( 0.296724)
exclusive 7.000000 0.000000 7.000000 ( 7.006737)
my_exclusive 5.040000 0.010000 5.050000 ( 5.294778)
exclusive 6.950000 0.000000 6.950000 ( 7.170255)
my_exclusive 4.970000 0.000000 4.970000 ( 4.964166)

(850MHz PIII, linux 2.4.21, ruby 1.9.0)

Can anyone see any reason not to use it? There is slightly different
semantics w.r.t. subclasses of Thread that redefine #critical, but I
think the difference is benign. Also, there is no way that
Thread.critical can raise an exception (in the curreny ruby source), so
that's not going to cause a problem with the placement of the "old =
critical" line.

The main reason I'm interested in this is some heavily threaded code
that spends 20% of process time in Thread.exclusive (according to the
profiler). I can probably improve this by using Thread.critical and
Thread.critical= instead, but why not improve Thread.exclusive itself?

The new implementation (actually I've been using it for a year without
knowing it was different from thread.rb) seems quite stable in my stress
tests.

----

require 'thread'
require 'benchmark'

class Thread
# Slightly faster (30%) replacement for Thread.exclusive.
def self.my_exclusive
old = critical
self.critical = true
yield
ensure
self.critical = old
end
end

# ---- From thread.rb: ----
#
# class Thread
# #
# # FIXME: not documented in Pickaxe or Nutshell.
# #
# def Thread.exclusive
# _old = Thread.critical
# begin
# Thread.critical = true
# return yield
# ensure
# Thread.critical = _old
# end
# end
# end

Benchmark.bm(15) do |bm|

n = 1_000_000

bm.report "warmup" do
n.times do
end
end

bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end

bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end

bm.report "exclusive" do
n.times do
Thread.exclusive do
end
end
end

bm.report "my_exclusive" do
n.times do
Thread.my_exclusive do
end
end
end

end
 
J

Joel VanderWerf

Joel said:
The main reason I'm interested in this is some heavily threaded code
that spends 20% of process time in Thread.exclusive (according to the
profiler). I can probably improve this by using Thread.critical and
Thread.critical= instead, but why not improve Thread.exclusive itself?

Yep, I just verified that replacing Thread.exclusive (the fast version)
with Thread.critical and Thread.critical= improves speed by about 20%.
But this is ignoring the possibility of exceptions in some places, so I
would have to add some rescue clauses, and that would narrow the difference.

None of this is terribly important, but if I can get a performance
improvement for free, I'll take it.
 
N

nobu.nokada

Hi,

At Sat, 17 Jan 2004 16:16:38 +0900,
Joel said:
Can anyone see any reason not to use it? There is slightly different
semantics w.r.t. subclasses of Thread that redefine #critical, but I
think the difference is benign. Also, there is no way that
Thread.critical can raise an exception (in the curreny ruby source), so
that's not going to cause a problem with the placement of the "old =
critical" line.

Agree. It would be used as Thread.exclusive in almost cases.
The gain seems to be mainly caused by replacing constant
references with self.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,785
Latest member
undedgini

Latest Threads

Top