perfmonger 0.12.1 → 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9610baac2556f61a8deb2cab5c7d4c10dac9c7da69c0c07a2f7d2b5f2414199e
4
- data.tar.gz: 1e94e2c14421eabddd25f60abb8ef6e749aa57a557c4d661830b52fc5f91d7ca
3
+ metadata.gz: 9b1f5e883802377df1cc422ab0e100f2445bdaafb7d77da2ddcb279232cd63b4
4
+ data.tar.gz: b3cf4f9bd787f1b9b47dcff4da7480d8c30385c89a3785ad0793c5c40703dd06
5
5
  SHA512:
6
- metadata.gz: 7a5f69061b79e2dcafe707bdb24b5a7be0443df2130bd928f33a7aba7a56623a946979ac22e0a82ce367f6d8d17d66facaf7286c6fe1c09016f8cedfc43dc5f6
7
- data.tar.gz: 9754fb8acc4b1a521c2daf2a67017d95ec018b414f7f808989589efa498f3f66003f93d1d8d6aa7455a008259486f7ea71dae8c8d2934c52ed0b55e9dd0b0a1f
6
+ metadata.gz: cdca2aa8a3ad76a274cdc142f1738e12578dc06117de98a1e24e41aee5604452a113becdd506df19d49b5ccf7aa1e1d1eaa58ab8a52b1fd121181318f3fdad51
7
+ data.tar.gz: 76697490438d0b364be27504a7db0697d33b9f3bc5dc56f11db8dc89f5a1f682a270ad2d50bbedb40852ea759a0cf98708cc0fd159bc73568f17e11da2f43de7
data/NEWS CHANGED
@@ -1,4 +1,28 @@
1
- ## 20XX-XX-XX: PerfMonger 0.13.0
1
+ ## 2021-XX-XX: PerfMonger 0.15.0
2
+
3
+ ## 2021-12-01: PerfMonger 0.14.2
4
+ * Bugfix
5
+ * [player] subcommand:
6
+ * Read stdin if no argument is given (required behaviour for live subcommand)
7
+
8
+ ## 2021-12-01: PerfMonger 0.14.1
9
+ * Changes
10
+ * [plot] subcommand:
11
+ * Skip plotting memory usage if it is not recorded
12
+
13
+ ## 2021-07-27: PerfMonger 0.14.0
14
+ * New features
15
+ * [plot] subcommand:
16
+ * Added memory usage plot
17
+ * Changes
18
+ * [record] subcommand:
19
+ * Additionaly record 'Hugepagesize' in memory usage
20
+
21
+ ## 2021-07-26: PerfMonger 0.13.1
22
+ * New features
23
+ * [play] subcommand:
24
+ * Added --disk-only option to filter results of not interesting disks
25
+ * Note: v0.13.0 is yanked from rubygems.org
2
26
 
3
27
  ## 2021-07-08: PerfMonger 0.12.1
4
28
  * Bug fixes
@@ -9,16 +9,19 @@ import (
9
9
  "fmt"
10
10
  "io"
11
11
  "os"
12
+ "regexp"
12
13
 
13
14
  projson "github.com/hayamiz/go-projson"
15
+ core "github.com/hayamiz/perfmonger/core"
14
16
  ss "github.com/hayamiz/perfmonger/core/subsystem"
15
- core "github.com/hayamiz/perfmonger/core"
16
17
  )
17
18
 
18
19
  type PlayerOption struct {
19
- logfile string
20
- color bool
21
- pretty bool
20
+ logfile string
21
+ color bool
22
+ pretty bool
23
+ disk_only string
24
+ disk_only_regex *regexp.Regexp
22
25
  }
23
26
 
24
27
  var option PlayerOption
@@ -50,10 +53,11 @@ func showInterruptStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cu
50
53
  return nil
51
54
  }
52
55
 
53
- func showDiskStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
54
- dusage, err := ss.GetDiskUsage(
56
+ func showDiskStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord, disk_only_regex *regexp.Regexp) error {
57
+ dusage, err := ss.GetDiskUsage1(
55
58
  prev_rec.Time, prev_rec.Disk,
56
- cur_rec.Time, cur_rec.Disk)
59
+ cur_rec.Time, cur_rec.Disk,
60
+ option.disk_only_regex)
57
61
  if err != nil {
58
62
  return err
59
63
  }
@@ -94,7 +98,9 @@ func showMemStat(printer *projson.JsonPrinter, cur_rec *ss.StatRecord) error {
94
98
  return nil
95
99
  }
96
100
 
97
- func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
101
+ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord,
102
+ disk_only_regex *regexp.Regexp) error {
103
+
98
104
  printer.Reset()
99
105
  if option.pretty {
100
106
  printer.SetStyle(projson.SmartStyle)
@@ -102,6 +108,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
102
108
  if option.color {
103
109
  printer.SetColor(true)
104
110
  }
111
+
105
112
  printer.BeginObject()
106
113
  printer.PutKey("time")
107
114
  printer.PutFloatFmt(float64(cur_rec.Time.UnixNano())/1e9, "%.3f")
@@ -122,7 +129,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
122
129
  }
123
130
  }
124
131
  if cur_rec.Disk != nil {
125
- err := showDiskStat(printer, prev_rec, cur_rec)
132
+ err := showDiskStat(printer, prev_rec, cur_rec, disk_only_regex)
126
133
  if err != nil {
127
134
  return err
128
135
  }
@@ -148,10 +155,25 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
148
155
  func parseArgs() {
149
156
  flag.BoolVar(&option.color, "color", false, "Use colored JSON output")
150
157
  flag.BoolVar(&option.pretty, "pretty", false, "Use human readable JSON output")
158
+ flag.StringVar(&option.disk_only, "disk-only", "", "Select disk devices by regex")
151
159
 
152
160
  flag.Parse()
153
161
 
154
- option.logfile = flag.Arg(0)
162
+ option.disk_only_regex = nil
163
+
164
+ if option.disk_only != "" {
165
+ var err error
166
+ option.disk_only_regex, err = regexp.Compile(option.disk_only)
167
+ if err != nil {
168
+ panic(err)
169
+ }
170
+ }
171
+
172
+ if len(flag.Args()) < 1 {
173
+ option.logfile = "-"
174
+ } else {
175
+ option.logfile = flag.Arg(0)
176
+ }
155
177
  }
156
178
 
157
179
  func main() {
@@ -160,7 +182,7 @@ func main() {
160
182
 
161
183
  parseArgs()
162
184
 
163
- if option.logfile == "" {
185
+ if option.logfile == "-" {
164
186
  in = os.Stdin
165
187
  } else {
166
188
  f, err := os.Open(option.logfile)
@@ -219,7 +241,7 @@ func main() {
219
241
  panic(err)
220
242
  }
221
243
 
222
- err = showStat(printer, prev_rec, cur_rec)
244
+ err = showStat(printer, prev_rec, cur_rec, option.disk_only_regex)
223
245
  if err != nil {
224
246
  printer.Reset()
225
247
  fmt.Fprintln(os.Stderr, "skip by err")
@@ -0,0 +1,24 @@
1
+ # perfmonger-plot-formatter
2
+
3
+ `perfmonger-plot-formatter` is a command to generate data files for plotting
4
+ various metrices recorded by `perfmonger-recorder`.
5
+
6
+ ## Notes on memory usage records
7
+
8
+ ### `free(1)` compatible summarization
9
+
10
+ - total: `MemStat.MemTotal`
11
+ - used: `if (memUsed < 0) { MemStat.MemTotal - MemStat.MemFree } else { memUsed }`
12
+ - memUsed := `MemStat.MemTotal - MemStat.MemFree - mainCached - MemStat.Buffers`
13
+ - mainCached := `MemStat.Cached + MemStat.SReclaimable`
14
+ - free: `MemStat.MemFree`
15
+ - shared: `MemStat.Shmem`
16
+ - buffers: `MemStat.Buffers`
17
+ - cache: `mainCached`
18
+ - mainCached := `MemStat.Cached + MemStat.SReclaimable`
19
+ - available: `MemStat.MemAvailable`
20
+
21
+ ### Additional info
22
+
23
+ - hugeTotal: `MemStat.HugePages_Total`
24
+ - hugeUsed: `MemStat.HugePages_Total - MemStat.HugePages_Free`
@@ -13,14 +13,16 @@ import (
13
13
  "os"
14
14
  "regexp"
15
15
  "sort"
16
+ "strings"
16
17
 
17
- ss "github.com/hayamiz/perfmonger/core/subsystem"
18
18
  "github.com/hayamiz/perfmonger/core"
19
+ ss "github.com/hayamiz/perfmonger/core/subsystem"
19
20
  )
20
21
 
21
22
  type CmdOption struct {
22
23
  DiskFile string
23
24
  CpuFile string
25
+ MemFile string
24
26
  PerfmongerFile string
25
27
  disk_only string
26
28
  disk_only_regex *regexp.Regexp
@@ -31,8 +33,9 @@ func parseArgs() *CmdOption {
31
33
 
32
34
  opt := new(CmdOption)
33
35
 
34
- flag.StringVar(&opt.DiskFile, "diskfile", "./disk.dat", "Disk performance data file")
35
- flag.StringVar(&opt.CpuFile, "cpufile", "./cpu.dat", "CPU performance data file")
36
+ flag.StringVar(&opt.DiskFile, "diskfile", "./disk.dat", "Disk usage data file for gnuplot")
37
+ flag.StringVar(&opt.CpuFile, "cpufile", "./cpu.dat", "CPU usage data file for gnuplot")
38
+ flag.StringVar(&opt.MemFile, "memfile", "./mem.dat", "Memory usage data file for gnuplot")
36
39
  flag.StringVar(&opt.PerfmongerFile, "perfmonger", "", "Perfmonger log file")
37
40
  flag.StringVar(&opt.disk_only, "disk-only",
38
41
  "", "Select disk devices by regex")
@@ -80,6 +83,13 @@ type DiskDatTmpFile struct {
80
83
  Idx int
81
84
  }
82
85
 
86
+ type MemDatTmpFile struct {
87
+ Name string
88
+ Path string
89
+ File *os.File
90
+ Writer *bufio.Writer
91
+ }
92
+
83
93
  type CpuDatTmpFile struct {
84
94
  CoreId int
85
95
  Path string
@@ -118,6 +128,20 @@ func makeCpuDatTmpFile(coreid int) *CpuDatTmpFile {
118
128
  return ret
119
129
  }
120
130
 
131
+ func makeMemDatTmpFile() *MemDatTmpFile {
132
+ ret := new(MemDatTmpFile)
133
+
134
+ f, err := ioutil.TempFile("", "perfmonger-mem")
135
+ if err != nil {
136
+ panic(err)
137
+ }
138
+ ret.File = f
139
+ ret.Path = f.Name()
140
+ ret.Writer = bufio.NewWriter(f)
141
+
142
+ return ret
143
+ }
144
+
121
145
  func printCoreUsage(writer *bufio.Writer, elapsed_time float64, coreusage *ss.CpuCoreUsage) {
122
146
  writer.WriteString(
123
147
  fmt.Sprintf("%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",
@@ -133,6 +157,80 @@ func printCoreUsage(writer *bufio.Writer, elapsed_time float64, coreusage *ss.Cp
133
157
  coreusage.Idle))
134
158
  }
135
159
 
160
+ func printMemUsage(writer *bufio.Writer, elapsed_time float64, mem *ss.MemStat) {
161
+ if mem == nil {
162
+ writer.WriteString("#")
163
+ writer.WriteString(
164
+ strings.Join([]string{
165
+ "elapsed_time", // 1
166
+ "mem_total", // 2
167
+ "mem_used", // 3
168
+ "mem_free", // 4
169
+ "buffers", // 5
170
+ "cached", // 6
171
+ "swap_cached", // 7
172
+ "active", // 8
173
+ "inactive", // 9
174
+ "swap_total", // 10
175
+ "swap_free", // 11
176
+ "dirty", // 12
177
+ "writeback", // 13
178
+ "anon_pages", // 14
179
+ "mapped", // 15
180
+ "shmem", // 16
181
+ "slab", // 17
182
+ "s_reclaimable", // 18
183
+ "s_unreclaim", // 19
184
+ "kernel_stack", // 20
185
+ "page_tables", // 21
186
+ "nfs_unstable", // 22
187
+ "bounce", // 23
188
+ "commit_limit", // 24
189
+ "committed_as", // 25
190
+ "anon_huge_pages", // 26
191
+ "huge_pages_total", // 27
192
+ "huge_pages_free", // 28
193
+ "huge_pages_rsvd", // 29
194
+ "huge_pages_surp", // 30
195
+ "hugepagesize"}, // 31
196
+ "\t"))
197
+ writer.WriteString("\n")
198
+ } else {
199
+ writer.WriteString(fmt.Sprintf("%f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
200
+ elapsed_time,
201
+ mem.MemTotal,
202
+ mem.MemTotal-mem.MemFree-mem.Buffers-mem.Cached-mem.SReclaimable,
203
+ mem.MemFree,
204
+ mem.Buffers,
205
+ mem.Cached,
206
+ mem.SwapCached,
207
+ mem.Active,
208
+ mem.Inactive,
209
+ mem.SwapTotal,
210
+ mem.SwapFree,
211
+ mem.Dirty,
212
+ mem.Writeback,
213
+ mem.AnonPages,
214
+ mem.Mapped,
215
+ mem.Shmem,
216
+ mem.Slab,
217
+ mem.SReclaimable,
218
+ mem.SUnreclaim,
219
+ mem.KernelStack,
220
+ mem.PageTables,
221
+ mem.NFS_Unstable,
222
+ mem.Bounce,
223
+ mem.CommitLimit,
224
+ mem.Committed_AS,
225
+ mem.AnonHugePages,
226
+ mem.HugePages_Total,
227
+ mem.HugePages_Free,
228
+ mem.HugePages_Rsvd,
229
+ mem.HugePages_Surp,
230
+ mem.Hugepagesize))
231
+ }
232
+ }
233
+
136
234
  func main() {
137
235
  opt := parseArgs()
138
236
 
@@ -193,6 +291,13 @@ func main() {
193
291
  cpu_writer.WriteString("# All cpu usage\n")
194
292
  cpu_writer.WriteString("# elapsed_time %usr %nice %sys %iowait %hardirq %softirq %steal %guest %idle\n")
195
293
 
294
+ f, err = os.Create(opt.MemFile)
295
+ if err != nil {
296
+ panic(err)
297
+ }
298
+ defer f.Close()
299
+ mem_writer := bufio.NewWriter(f)
300
+
196
301
  for {
197
302
  prev_rec := &records[curr^1]
198
303
  cur_rec := &records[curr]
@@ -284,6 +389,12 @@ func main() {
284
389
  }
285
390
  printCoreUsage(cpu_writer, prev_rec.Time.Sub(t0).Seconds(), cusage.All)
286
391
 
392
+ if !meta_set {
393
+ // print column labels
394
+ printMemUsage(mem_writer, prev_rec.Time.Sub(t0).Seconds(), nil)
395
+ }
396
+ printMemUsage(mem_writer, prev_rec.Time.Sub(t0).Seconds(), cur_rec.Mem)
397
+
287
398
  curr ^= 1
288
399
  meta_set = true
289
400
  }
@@ -332,6 +443,7 @@ func main() {
332
443
  os.Remove(cpu_dat.Path)
333
444
  }
334
445
  cpu_writer.Flush()
446
+ mem_writer.Flush()
335
447
 
336
448
  json_enc := json.NewEncoder(os.Stdout)
337
449
  json_enc.Encode(meta)
@@ -12,8 +12,8 @@ import (
12
12
  "sort"
13
13
 
14
14
  projson "github.com/hayamiz/go-projson"
15
- ss "github.com/hayamiz/perfmonger/core/subsystem"
16
15
  "github.com/hayamiz/perfmonger/core"
16
+ ss "github.com/hayamiz/perfmonger/core/subsystem"
17
17
  )
18
18
 
19
19
  type SummaryOption struct {
@@ -39,6 +39,7 @@ func parseArgs() {
39
39
  flag.Parse()
40
40
 
41
41
  if len(flag.Args()) < 1 {
42
+ fmt.Fprintln(os.Stderr, "Insufficient argument")
42
43
  os.Exit(1)
43
44
  }
44
45
 
@@ -469,6 +469,8 @@ func ReadMemStat(record *StatRecord) error {
469
469
  mem_stat.HugePages_Free = val
470
470
  case "HugePages_Total:":
471
471
  mem_stat.HugePages_Total = val
472
+ case "Hugepagesize:":
473
+ mem_stat.Hugepagesize = val
472
474
  case "AnonHugePages:":
473
475
  mem_stat.AnonHugePages = val
474
476
  case "Committed_AS:":
@@ -132,6 +132,7 @@ type MemStat struct {
132
132
  HugePages_Free int64
133
133
  HugePages_Rsvd int64
134
134
  HugePages_Surp int64
135
+ Hugepagesize int64
135
136
  }
136
137
 
137
138
  type StatRecord struct {
@@ -286,6 +287,7 @@ func (entry *MemStat) Clear() {
286
287
  entry.HugePages_Free = 0
287
288
  entry.HugePages_Rsvd = 0
288
289
  entry.HugePages_Surp = 0
290
+ entry.Hugepagesize = 0
289
291
  }
290
292
 
291
293
  func NewStatRecord() *StatRecord {
Binary file
@@ -26,6 +26,10 @@ EOS
26
26
  @pretty = true
27
27
  end
28
28
 
29
+ @disk_only_regex = nil
30
+ @parser.on('--disk-only REGEX', "Select disk devices that matches REGEX (Ex. 'sd[b-d]')") do |regex|
31
+ @disk_only_regex = regex
32
+ end
29
33
  end
30
34
 
31
35
  def parse_args(argv)
@@ -62,6 +66,12 @@ EOS
62
66
  if @pretty
63
67
  cmd << "-pretty"
64
68
  end
69
+
70
+ if @disk_only_regex
71
+ cmd << "-disk-only"
72
+ cmd << @disk_only_regex
73
+ end
74
+
65
75
  cmd << @logfile
66
76
 
67
77
  Process.exec(*cmd)
@@ -145,10 +145,13 @@ EOS
145
145
 
146
146
  @disk_dat = File.expand_path("disk.dat", @tmpdir)
147
147
  @cpu_dat = File.expand_path("cpu.dat", @tmpdir)
148
+ @mem_dat = File.expand_path("mem.dat", @tmpdir)
148
149
 
149
150
  meta_json = nil
150
- cmd = [formatter_bin, "-perfmonger", @data_file, "-cpufile", @cpu_dat,
151
- "-diskfile", @disk_dat]
151
+ cmd = [formatter_bin, "-perfmonger", @data_file,
152
+ "-cpufile", @cpu_dat,
153
+ "-diskfile", @disk_dat,
154
+ "-memfile", @mem_dat]
152
155
  if @disk_only_regex
153
156
  cmd << "-disk-only"
154
157
  cmd << @disk_only
@@ -164,6 +167,7 @@ EOS
164
167
 
165
168
  plot_disk(meta)
166
169
  plot_cpu(meta)
170
+ plot_mem(meta)
167
171
 
168
172
  FileUtils.rm_rf(@tmpdir)
169
173
 
@@ -508,6 +512,144 @@ EOS
508
512
  end
509
513
  end # def
510
514
 
515
+ def plot_mem(meta)
516
+ pdf_filename = @output_prefix + 'mem.pdf'
517
+ gp_filename = @output_prefix + 'mem.gp'
518
+ dat_filename = @output_prefix + 'mem.dat'
519
+
520
+ unless File.exists?(dat_filename)
521
+ $stderr.puts("WARN: memory usage info is not available.")
522
+ return
523
+ end
524
+
525
+ if @output_type != 'pdf'
526
+ img_filename = @output_prefix + 'cpu.' + @output_type
527
+ else
528
+ img_filename = nil
529
+ end
530
+
531
+ start_time = meta["start_time"]
532
+ end_time = meta["end_time"]
533
+
534
+ mem_scaling = 2.0**20 # KB -> GB
535
+
536
+ # "elapsed_time", // 1
537
+ # "mem_total", // 2
538
+ # "mem_used", // 3
539
+ # "mem_free", // 4
540
+ # "buffers", // 5
541
+ # "cached", // 6
542
+ # "swap_cached", // 7
543
+ # "active", // 8
544
+ # "inactive", // 9
545
+ # "swap_total", // 10
546
+ # "swap_free", // 11
547
+ # "dirty", // 12
548
+ # "writeback", // 13
549
+ # "anon_pages", // 14
550
+ # "mapped", // 15
551
+ # "shmem", // 16
552
+ # "slab", // 17
553
+ # "s_reclaimable", // 18
554
+ # "s_unreclaim", // 19
555
+ # "kernel_stack", // 20
556
+ # "page_tables", // 21
557
+ # "nfs_unstable", // 22
558
+ # "bounce", // 23
559
+ # "commit_limit", // 24
560
+ # "committed_as", // 25
561
+ # "anon_huge_pages", // 26
562
+ # "huge_pages_total", // 27
563
+ # "huge_pages_free", // 28
564
+ # "huge_pages_rsvd", // 29
565
+ # "huge_pages_surp"}, // 30
566
+ # "hugepagesize"}, // 31
567
+
568
+ Dir.chdir(@tmpdir) do
569
+ total = `tail -n+2 #{dat_filename}|head -n1`.split[1].to_f
570
+ if total == 0.0
571
+ raise RuntimeError.new("Failed to get MemTotal value from mem.dat file: #{dat_filename}")
572
+ end
573
+
574
+ gpfile = File.open(gp_filename, 'w')
575
+
576
+ pdf_file = File.join(@output_dir, "mem.pdf")
577
+ gpfile.puts <<EOS
578
+ set term pdfcairo enhanced color size 6in,2.5in
579
+ set title "Memory usage"
580
+ set output "#{pdf_filename}"
581
+ set key outside center bottom horizontal
582
+ set size 1.0, 1.0
583
+
584
+ set xlabel "elapsed time [sec]"
585
+ set ylabel "memory usage [GB]"
586
+
587
+ # scaling
588
+ s = #{mem_scaling}
589
+
590
+ set grid
591
+ set xrange [#{@offset_time}:#{end_time - start_time}]
592
+ set yrange [0:#{total * 1.2}/s]
593
+
594
+ # line styles
595
+ set style line 1 lt 1 lc rgb '#66C2A5' # teal
596
+ set style line 2 lt 1 lc rgb '#FC8D62' # orange
597
+ set style line 3 lt 1 lc rgb '#8DA0CB' # lilac
598
+ set style line 4 lt 1 lc rgb '#E78AC3' # magentat
599
+ set style line 5 lt 1 lc rgb '#A6D854' # lime green
600
+ set style line 6 lt 1 lc rgb '#FFD92F' # banana
601
+ set style line 7 lt 1 lc rgb '#E5C494' # tan
602
+ set style line 8 lt 1 lc rgb '#B3B3B3' # grey
603
+
604
+ # palette
605
+ set palette maxcolors 8
606
+ set palette defined ( 0 '#66C2A5',\
607
+ 1 '#FC8D62',\
608
+ 2 '#8DA0CB',\
609
+ 3 '#E78AC3',\
610
+ 4 '#A6D854',\
611
+ 5 '#FFD92F',\
612
+ 6 '#E5C494',\
613
+ 7 '#B3B3B3' )
614
+
615
+ used(total, free, cached, buffers, srecl) = \\
616
+ ( (total - free - cache(cached, srecl) - buffers < 0) ? \\
617
+ (total - free) : \\
618
+ (total - free - cache(cached, srecl) - buffers) )
619
+
620
+ cache(cached, srecl) = cached + srecl
621
+
622
+ plot "#{dat_filename}" usi 1:($4/s+$5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 8 ti "free", \\
623
+ "#{dat_filename}" usi 1:($5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 3 ti "buffers", \\
624
+ "#{dat_filename}" usi 1:(cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 5 ti "cached", \\
625
+ "#{dat_filename}" usi 1:($16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 6 ti "shared", \\
626
+ "#{dat_filename}" usi 1:(used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 2 ti "used", \\
627
+ "#{dat_filename}" usi 1:(($27-$28)*$31/s) wi lines dt (4,4) lc rgb 'black' lw 2.5 ti 'used (hugepage)'
628
+
629
+ EOS
630
+
631
+ gpfile.close
632
+ system("gnuplot #{gpfile.path}")
633
+
634
+ if @output_type != 'pdf'
635
+ system("convert -density 150 -background white #{pdf_filename} #{img_filename}")
636
+ end
637
+ end # chdir
638
+
639
+ copy_targets = []
640
+ copy_targets << pdf_filename
641
+ copy_targets << img_filename if img_filename
642
+
643
+ if @save_gpfiles
644
+ copy_targets << gp_filename
645
+ copy_targets << dat_filename
646
+ end
647
+
648
+ copy_targets.each do |target|
649
+ FileUtils.copy(File.join(@tmpdir, target), @output_dir)
650
+ end
651
+ end # def
652
+
511
653
  private
512
654
  def factors(n)
513
655
  (2..([n, n / 2].max).to_i).select do |x|
@@ -1,3 +1,3 @@
1
1
  module PerfMonger
2
- VERSION = "0.12.1"
2
+ VERSION = "0.14.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfmonger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuto HAYAMIZU
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,6 +102,7 @@ files:
102
102
  - core/Makefile
103
103
  - core/build.sh
104
104
  - core/cmd/perfmonger-player/perfmonger-player.go
105
+ - core/cmd/perfmonger-plot-formatter/README.md
105
106
  - core/cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go
106
107
  - core/cmd/perfmonger-recorder/perfmonger-recorder.go
107
108
  - core/cmd/perfmonger-summarizer/perfmonger-summarizer.go