Project

General

Profile

Bug #10009 » test_thread_sched.rb

ariveira (Alexandre Riveira), 08/16/2014 03:55 PM

 
# test_thread_sched.rb
#
# use this file for analyze gil/gvl em linux environment
# time should be as near as possible to 20 seconds
# ruby with 100% cpu usage time problems with input/output
#
# use --postgres to analyze input/output problem with 100% cpu usage
# use --taskset to force use one processor
#
# Written & maintained by Alexandre Riveira <alexandre@objectdata.com.br>.
# This program is free software. You can re-distribute and/or
# modify this program under the same terms as Ruby itself,
# Ruby Distribute License.

if ARGV.include? '--help'
puts "usage: ruby test_thread_sched.rb --postgres --taskset"
exit
end

#postgres
postgres = ARGV.include? '--postgres'
require 'pg' if postgres

# taskset to analyze linux environment for 1 processor
taskset = ARGV.include? '--taskset'
system("taskset -c -p 2 #{Process.pid}") if taskset

# general time
time_start = Time.now

# align for best view
align = 15

# first test 10 seconds for one thread
puts "first test..."
t1 = Thread.new do
Thread.current[:target] = 0
loop do
Thread.current[:target] += 1
end
end

# print time for sleep with one thread using 100% cpu
10.times do
time_local = Time.now
sleep(1)
puts "first".ljust(align, '.') + ": #{t1[:target]}"
puts "time".ljust(15, '.') + ": #{Time.now - time_local} secs\n\n"
end

puts "\n" * 3

# second test 10 seconds for three threads
puts "second test..."
t1[:target] = 0

t2 = Thread.new do
Thread.current[:target] = 0
loop do
Thread.current[:target] += 1
end
end

t3 = Thread.new do
Thread.current[:target] = 0
if postgres
conn = PGconn.open(:dbname => 'postgres', :user => 'postgres', :host => 'localhost')
loop do
conn.exec("SELECT * FROM pg_stat_activity")
Thread.current[:target] += 1
end
else
loop do
Thread.current[:target] += 1
end
end
end

label = postgres ? 'postgres' : 'three'
10.times do
time_local = Time.now
sleep(1)
puts "first".ljust(align, '.') + ": #{t1[:target]}"
puts "second".ljust(align, '.') + ": #{t2[:target]}"
puts label.ljust(align, '.') + ": #{t3[:target]}"
puts "time".ljust(15, '.') + ": #{Time.now - time_local} secs\n\n"
end

# resume
time = Time.now - time_start
total = t1[:target] + t2[:target] + t3[:target]

# processor
lines = File.readlines("/proc/cpuinfo")
model = lines.detect{|line| line.start_with? 'model name'}.split(':').last
number = lines.count{|line| line.start_with? 'processor'}
puts "processor".ljust(align, '.') + ": #{model} with (#{number} processores)".gsub(/\s+/, ' ')
puts "taskset".ljust(align, '.') + ": #{taskset}"

# ruby version
puts "ruby version".ljust(align, '.') + ": #{RUBY_VERSION}-#{RUBY_ENGINE}"

# total
puts "total".ljust(align, '.') + ": #{total}"
puts "postgres".ljust(align, '.') + ": #{t3[:target]}" if postgres
puts "time".ljust(align, '.') + ": #{time} (ideal value of 20 seconds)"
(5-5/8)