Permalink
Browse files

Add future benchmarks from rubyconf 2015

  • Loading branch information...
pitr-ch committed Dec 8, 2015
1 parent e17e6d1 commit 7cb2dc6130df19e53f2157a71c90e2153d60a467
Showing with 620 additions and 3 deletions.
  1. +4 −0 Gemfile
  2. +20 −0 benchmarks/default.config.rb
  3. +31 −0 benchmarks/futures-rubyconf2015.config.rb
  4. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-cas-complete.rb
  5. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-cas-fulfill.rb
  6. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-cas-new.rb
  7. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-cas-value.rb
  8. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-complete.rb
  9. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-fulfill.rb
  10. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-new.rb
  11. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/cr-value.rb
  12. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/mutex-complete.rb
  13. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/mutex-fulfill.rb
  14. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/mutex-new.rb
  15. +3 −0 benchmarks/futures-rubyconf2015/benchmarks/mutex-value.rb
  16. +18 −0 benchmarks/futures-rubyconf2015/benchmarks/special-complete.rb
  17. +18 −0 benchmarks/futures-rubyconf2015/benchmarks/special-fulfill.rb
  18. +18 −0 benchmarks/futures-rubyconf2015/benchmarks/special-new.rb
  19. +18 −0 benchmarks/futures-rubyconf2015/benchmarks/special-value.rb
  20. +23 −0 benchmarks/futures-rubyconf2015/lib/bench_complete.rb
  21. +20 −0 benchmarks/futures-rubyconf2015/lib/bench_fulfill.rb
  22. +20 −0 benchmarks/futures-rubyconf2015/lib/bench_new.rb
  23. +24 −0 benchmarks/futures-rubyconf2015/lib/bench_value.rb
  24. +2 −0 benchmarks/futures-rubyconf2015/lib/concurrent_needed.rb
  25. +83 −0 benchmarks/futures-rubyconf2015/lib/cr_cas_future.rb
  26. +49 −0 benchmarks/futures-rubyconf2015/lib/cr_future.rb
  27. +19 −0 benchmarks/futures-rubyconf2015/lib/example_reordering_ivar.rb
  28. +39 −0 benchmarks/futures-rubyconf2015/lib/example_usage_of_future.rb
  29. +36 −0 benchmarks/futures-rubyconf2015/lib/gvl_future.rb
  30. +43 −0 benchmarks/futures-rubyconf2015/lib/jruby_future.rb
  31. +37 −0 benchmarks/futures-rubyconf2015/lib/mutex_future.rb
  32. +46 −0 benchmarks/futures-rubyconf2015/lib/rbx_future.rb
  33. +9 −0 benchmarks/readme.md
  34. +2 −0 lib/concurrent/synchronization.rb
  35. +1 −1 lib/concurrent/synchronization/abstract_lockable_object.rb
  36. +4 −2 lib/concurrent/synchronization/truffle_lockable_object.rb
View
@@ -25,3 +25,7 @@ group :testing do
gem 'simplecov', '~> 0.10.0', :require => false
gem 'coveralls', '~> 0.8.2', :require => false
end
group :benchmarks do
gem 'bench9000'
end
@@ -0,0 +1,20 @@
rbenv '2.2.3'
rbenv 'jruby-9.0.4.0-indy',
'jruby-9.0.4.0',
'-Xcompile.invokedynamic=true'
rbenv 'rbx-2.5.8'
rbenv 'jruby-dev-truffle-graal',
'jruby-master+graal-dev',
'-J-Xmx2G -X+T'
binary 'baseline', 'false'
rubies = ['baseline', '2.2.3', 'jruby-9.0.4.0-indy', 'rbx-2.5.8']
rubies = ['2.2.3', 'jruby-9.0.4.0-indy', 'rbx-2.5.8']
implementation_group 'rubies', *rubies
implementation_group 'rubies+truffle', *rubies, 'jruby-dev-truffle-graal'
@@ -0,0 +1,31 @@
future_benchmarks = [
'mutex-complete',
'mutex-value',
'mutex-fulfill',
'special-complete',
'special-value',
'special-fulfill',
'cr-complete',
'cr-value',
'cr-fulfill',
'cr-cas-complete',
'cr-cas-value',
'cr-cas-fulfill',
]
future_new_benchmarks = [
'cr-cas-new',
'cr-new',
'special-new'
]
all_bechmarks = future_benchmarks + future_new_benchmarks
all_bechmarks.each do |name|
benchmark "future-#{name}",
"#{default_benchmarks_dir}/futures-rubyconf2015/benchmarks/#{name}.rb",
"-I #{default_benchmarks_dir}/futures-rubyconf2015/lib"
end
benchmark_group 'future', *(future_benchmarks.map { |v| "future-#{v}" })
benchmark_group 'future-new', *(all_bechmarks.map { |v| "future-#{v}" })
@@ -0,0 +1,3 @@
require 'cr_cas_future'
FutureImplementation = CRCasFuture
require 'bench_complete'
@@ -0,0 +1,3 @@
require 'cr_cas_future'
FutureImplementation = CRCasFuture
require 'bench_fulfill'
@@ -0,0 +1,3 @@
require 'cr_cas_future'
FutureImplementation = CRCasFuture
require 'bench_new'
@@ -0,0 +1,3 @@
require 'cr_cas_future'
FutureImplementation = CRCasFuture
require 'bench_value'
@@ -0,0 +1,3 @@
require 'cr_future'
FutureImplementation = CRFuture
require 'bench_complete'
@@ -0,0 +1,3 @@
require 'cr_future'
FutureImplementation = CRFuture
require 'bench_fulfill'
@@ -0,0 +1,3 @@
require 'cr_future'
FutureImplementation = CRFuture
require 'bench_new'
@@ -0,0 +1,3 @@
require 'cr_future'
FutureImplementation = CRFuture
require 'bench_value'
@@ -0,0 +1,3 @@
require 'mutex_future'
FutureImplementation = MutexFuture
require 'bench_complete'
@@ -0,0 +1,3 @@
require 'mutex_future'
FutureImplementation = MutexFuture
require 'bench_fulfill'
@@ -0,0 +1,3 @@
require 'mutex_future'
FutureImplementation = MutexFuture
require 'bench_new'
@@ -0,0 +1,3 @@
require 'mutex_future'
FutureImplementation = MutexFuture
require 'bench_value'
@@ -0,0 +1,18 @@
require 'concurrent_needed'
require 'concurrent/utility/engine'
FutureImplementation = case
when Concurrent.on_cruby?
require 'gvl_future'
GVLFuture
when Concurrent.on_rbx? || Concurrent.on_truffle?
require 'rbx_future'
RBXFuture
when Concurrent.on_jruby?
require 'jruby_future'
JRubyFuture
else
raise
end
require 'bench_complete'
@@ -0,0 +1,18 @@
require 'concurrent_needed'
require 'concurrent/utility/engine'
FutureImplementation = case
when Concurrent.on_cruby?
require 'gvl_future'
GVLFuture
when Concurrent.on_rbx? || Concurrent.on_truffle?
require 'rbx_future'
RBXFuture
when Concurrent.on_jruby?
require 'jruby_future'
JRubyFuture
else
raise
end
require 'bench_fulfill'
@@ -0,0 +1,18 @@
require 'concurrent_needed'
require 'concurrent/utility/engine'
FutureImplementation = case
when Concurrent.on_cruby?
require 'gvl_future'
GVLFuture
when Concurrent.on_rbx? || Concurrent.on_truffle?
require 'rbx_future'
RBXFuture
when Concurrent.on_jruby?
require 'jruby_future'
JRubyFuture
else
raise
end
require 'bench_new'
@@ -0,0 +1,18 @@
require 'concurrent_needed'
require 'concurrent/utility/engine'
FutureImplementation = case
when Concurrent.on_cruby?
require 'gvl_future'
GVLFuture
when Concurrent.on_rbx? || Concurrent.on_truffle?
require 'rbx_future'
RBXFuture
when Concurrent.on_jruby?
require 'jruby_future'
JRubyFuture
else
raise
end
require 'bench_value'
@@ -0,0 +1,23 @@
ITERATIONS = 2_500_000
def harness_input
FutureImplementation.new
end
def harness_sample(input)
ITERATIONS.times do
input.complete?
end
input.fulfill true
ITERATIONS.times do
input.complete?
end
end
def harness_verify(output)
true
end
require 'bench9000/harness'
@@ -0,0 +1,20 @@
ITERATIONS = 2_500_000
def harness_input
end
def harness_sample(input)
last_future = nil
ITERATIONS.times do |i|
last_future = FutureImplementation.new
last_future.fulfill i
end
last_future
end
def harness_verify(output)
output.value == ITERATIONS - 1
end
require 'bench9000/harness'
@@ -0,0 +1,20 @@
ITERATIONS = 2_500_000
def harness_input
end
def harness_sample(input)
last = nil
ITERATIONS.times do |i|
last = FutureImplementation.new
end
last
end
def harness_verify(output)
output.is_a? FutureImplementation
end
require 'bench9000/harness'
@@ -0,0 +1,24 @@
ITERATIONS = 5_000_000
def harness_input
f = FutureImplementation.new
f.fulfill 1
f
end
def harness_sample(input)
sum = 0
ITERATIONS.times do
sum += input.value
end
sum
end
def harness_verify(output)
output == ITERATIONS
end
require 'bench9000/harness'
@@ -0,0 +1,2 @@
concurrent_ruby_load_path = File.expand_path(File.join(File.dirname(__FILE__), '../../../lib'))
$LOAD_PATH << concurrent_ruby_load_path unless $LOAD_PATH.include? concurrent_ruby_load_path
@@ -0,0 +1,83 @@
require 'concurrent_needed'
require 'concurrent/synchronization'
require 'concurrent/atomics'
class CRCasFuture < Concurrent::Synchronization::Object
class Node < Concurrent::Synchronization::Object
attr_volatile(:awake)
safe_initialization!
def initialize(thread)
super()
@Thread = thread
self.awake = false
end
def thread
@Thread
end
end
safe_initialization!
PENDING = Object.new
attr_atomic(:atomic_value)
attr_atomic(:head)
def initialize
super
self.head = nil
self.atomic_value = PENDING
end
def complete?(value = atomic_value)
value != PENDING
end
def value
value = atomic_value
return value if complete? value
begin
while true
head = self.head
node = Node.new Thread.current
break if compare_and_set_head head, node
end
until complete?(value = atomic_value)
# may go to sleep even if completed, but it has a record by then
sleep
end
value
ensure
node.awake = true
wakeup head
end
end
def fulfill(value)
if compare_and_set_atomic_value(PENDING, value)
wakeup head
else
raise 'already fulfilled'
end
self
end
private
def wakeup(node)
return unless node
while true
break if node.awake
# has to be confirmed
node.thread.wakeup
Thread.pass
end
end
end
Oops, something went wrong.

0 comments on commit 7cb2dc6

Please sign in to comment.