test_thread_sched.rb

Alexandre Riveira, 08/16/2014 05:50 PM

Download (2.88 KB)

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

    
15
if ARGV.include? '--help'
16
  puts "usage: ruby test_thread_sched.rb --postgres --taskset"
17
  exit
18
end
19

    
20
#postgres
21
postgres = ARGV.include? '--postgres'
22
require 'pg' if postgres
23

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

    
28
# general time 
29
time_start = Time.now
30

    
31
# align for best view
32
align = 15
33

    
34
# first test 10 seconds for one thread
35
puts "first test..."
36
t1 = Thread.new do 
37
  Thread.current[:target] = 0
38
  loop do
39
    Thread.current[:target] += 1 
40
  end
41
end
42

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

    
51
puts "\n" * 3
52

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

    
57
t2 = Thread.new do
58
  Thread.current[:target] = 0
59
  loop do
60
    Thread.current[:target] += 1
61
  end
62
end
63

    
64
t3 = Thread.new do
65
  Thread.current[:target] = 0
66
  if postgres
67
    conn  = PGconn.open(:dbname => 'postgres', :user => 'postgres', :host => 'localhost')
68
    loop do
69
      conn.exec("SELECT * FROM pg_stat_activity")
70
      Thread.current[:target] += 1
71
    end
72
  else 
73
    loop do
74
      Thread.current[:target] += 1
75
    end
76
  end
77
end
78

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

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

    
93
#linux
94
puts "name".ljust(align, '.') + ": #{`uname -r -m`}"
95

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

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

    
106
# total
107
puts "total".ljust(align, '.') + ": #{total}"
108
puts "postgres".ljust(align, '.') + ": #{t3[:target]}" if postgres
109
puts "time".ljust(align, '.') + ": #{time} (ideal value of 20 seconds)"