Home | History | Annotate | Download | only in perf
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/test/perf/perf_test.h"
      6 
      7 #include <stdio.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "chrome/test/base/chrome_process_util.h"
     13 #include "testing/perf/perf_test.h"
     14 
     15 namespace perf_test {
     16 
     17 void PrintIOPerfInfo(const std::string& test_name,
     18                      const ChromeProcessList& chrome_processes,
     19                      base::ProcessId browser_pid) {
     20   PrintIOPerfInfo(stdout, test_name, chrome_processes, browser_pid);
     21 }
     22 
     23 void PrintIOPerfInfo(FILE* target,
     24                      const std::string& test_name,
     25                      const ChromeProcessList& chrome_processes,
     26                      base::ProcessId browser_pid) {
     27   fprintf(target, "%s", IOPerfInfoToString(test_name, chrome_processes,
     28                                            browser_pid).c_str());
     29 }
     30 
     31 std::string IOPerfInfoToString(const std::string& test_name,
     32                                const ChromeProcessList& chrome_processes,
     33                                base::ProcessId browser_pid) {
     34   size_t read_op_b = 0;
     35   size_t read_op_r = 0;
     36   size_t write_op_b = 0;
     37   size_t write_op_r = 0;
     38   size_t other_op_b = 0;
     39   size_t other_op_r = 0;
     40   size_t total_op_b = 0;
     41   size_t total_op_r = 0;
     42 
     43   size_t read_byte_b = 0;
     44   size_t read_byte_r = 0;
     45   size_t write_byte_b = 0;
     46   size_t write_byte_r = 0;
     47   size_t other_byte_b = 0;
     48   size_t other_byte_r = 0;
     49   size_t total_byte_b = 0;
     50   size_t total_byte_r = 0;
     51 
     52   std::string output;
     53   ChromeProcessList::const_iterator it;
     54   for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
     55     base::ProcessHandle process_handle;
     56     if (!base::OpenProcessHandle(*it, &process_handle)) {
     57       NOTREACHED();
     58       return output;
     59     }
     60 
     61     // TODO(sgk):  if/when base::ProcessMetrics returns real stats on mac:
     62     // scoped_ptr<base::ProcessMetrics> process_metrics(
     63     //     base::ProcessMetrics::CreateProcessMetrics(process_handle));
     64     scoped_ptr<ChromeTestProcessMetrics> process_metrics(
     65         ChromeTestProcessMetrics::CreateProcessMetrics(process_handle));
     66     base::IoCounters io_counters;
     67     memset(&io_counters, 0, sizeof(io_counters));
     68 
     69     if (process_metrics.get()->GetIOCounters(&io_counters)) {
     70       // Print out IO performance.  We assume that the values can be
     71       // converted to size_t (they're reported as ULONGLONG, 64-bit numbers).
     72       std::string chrome_name = (*it == browser_pid) ? "_b" : "_r";
     73 
     74       size_t read_op = static_cast<size_t>(io_counters.ReadOperationCount);
     75       size_t write_op = static_cast<size_t>(io_counters.WriteOperationCount);
     76       size_t other_op = static_cast<size_t>(io_counters.OtherOperationCount);
     77       size_t total_op = static_cast<size_t>(io_counters.ReadOperationCount +
     78                                             io_counters.WriteOperationCount +
     79                                             io_counters.OtherOperationCount);
     80 
     81       size_t read_byte = static_cast<size_t>(io_counters.ReadTransferCount
     82                                              / 1024);
     83       size_t write_byte = static_cast<size_t>(io_counters.WriteTransferCount
     84                                               / 1024);
     85       size_t other_byte = static_cast<size_t>(io_counters.OtherTransferCount
     86                                               / 1024);
     87       size_t total_byte = static_cast<size_t>((io_counters.ReadTransferCount +
     88                                                io_counters.WriteTransferCount +
     89                                                io_counters.OtherTransferCount)
     90                                               / 1024);
     91 
     92       if (*it == browser_pid) {
     93         read_op_b = read_op;
     94         write_op_b = write_op;
     95         other_op_b = other_op;
     96         total_op_b = total_op;
     97         read_byte_b = read_byte;
     98         write_byte_b = write_byte;
     99         other_byte_b = other_byte;
    100         total_byte_b = total_byte;
    101       } else {
    102         read_op_r += read_op;
    103         write_op_r += write_op;
    104         other_op_r += other_op;
    105         total_op_r += total_op;
    106         read_byte_r += read_byte;
    107         write_byte_r += write_byte;
    108         other_byte_r += other_byte;
    109         total_byte_r += total_byte;
    110       }
    111     }
    112 
    113     base::CloseProcessHandle(process_handle);
    114   }
    115 
    116   std::string t_name(test_name);
    117   AppendResult(output,
    118                "read_op_b",
    119                std::string(),
    120                "r_op_b" + t_name,
    121                read_op_b,
    122                "ops",
    123                false);
    124   AppendResult(output,
    125                "write_op_b",
    126                std::string(),
    127                "w_op_b" + t_name,
    128                write_op_b,
    129                "ops",
    130                false);
    131   AppendResult(output,
    132                "other_op_b",
    133                std::string(),
    134                "o_op_b" + t_name,
    135                other_op_b,
    136                "ops",
    137                false);
    138   AppendResult(output,
    139                "total_op_b",
    140                std::string(),
    141                "IO_op_b" + t_name,
    142                total_op_b,
    143                "ops",
    144                false);
    145 
    146   AppendResult(output,
    147                "read_byte_b",
    148                std::string(),
    149                "r_b" + t_name,
    150                read_byte_b,
    151                "kb",
    152                false);
    153   AppendResult(output,
    154                "write_byte_b",
    155                std::string(),
    156                "w_b" + t_name,
    157                write_byte_b,
    158                "kb",
    159                false);
    160   AppendResult(output,
    161                "other_byte_b",
    162                std::string(),
    163                "o_b" + t_name,
    164                other_byte_b,
    165                "kb",
    166                false);
    167   AppendResult(output,
    168                "total_byte_b",
    169                std::string(),
    170                "IO_b" + t_name,
    171                total_byte_b,
    172                "kb",
    173                false);
    174 
    175   AppendResult(output,
    176                "read_op_r",
    177                std::string(),
    178                "r_op_r" + t_name,
    179                read_op_r,
    180                "ops",
    181                false);
    182   AppendResult(output,
    183                "write_op_r",
    184                std::string(),
    185                "w_op_r" + t_name,
    186                write_op_r,
    187                "ops",
    188                false);
    189   AppendResult(output,
    190                "other_op_r",
    191                std::string(),
    192                "o_op_r" + t_name,
    193                other_op_r,
    194                "ops",
    195                false);
    196   AppendResult(output,
    197                "total_op_r",
    198                std::string(),
    199                "IO_op_r" + t_name,
    200                total_op_r,
    201                "ops",
    202                false);
    203 
    204   AppendResult(output,
    205                "read_byte_r",
    206                std::string(),
    207                "r_r" + t_name,
    208                read_byte_r,
    209                "kb",
    210                false);
    211   AppendResult(output,
    212                "write_byte_r",
    213                std::string(),
    214                "w_r" + t_name,
    215                write_byte_r,
    216                "kb",
    217                false);
    218   AppendResult(output,
    219                "other_byte_r",
    220                std::string(),
    221                "o_r" + t_name,
    222                other_byte_r,
    223                "kb",
    224                false);
    225   AppendResult(output,
    226                "total_byte_r",
    227                std::string(),
    228                "IO_r" + t_name,
    229                total_byte_r,
    230                "kb",
    231                false);
    232 
    233   return output;
    234 }
    235 
    236 void PrintMemoryUsageInfo(const std::string& test_name,
    237                           const ChromeProcessList& chrome_processes,
    238                           base::ProcessId browser_pid) {
    239   PrintMemoryUsageInfo(stdout, test_name, chrome_processes, browser_pid);
    240 }
    241 
    242 void PrintMemoryUsageInfo(FILE* target,
    243                           const std::string& test_name,
    244                           const ChromeProcessList& chrome_processes,
    245                           base::ProcessId browser_pid) {
    246   fprintf(target, "%s", MemoryUsageInfoToString(test_name, chrome_processes,
    247                                                 browser_pid).c_str());
    248 }
    249 
    250 std::string MemoryUsageInfoToString(const std::string& test_name,
    251                                     const ChromeProcessList& chrome_processes,
    252                                     base::ProcessId browser_pid) {
    253   size_t browser_virtual_size = 0;
    254   size_t browser_working_set_size = 0;
    255   size_t renderer_virtual_size = 0;
    256   size_t renderer_working_set_size = 0;
    257   size_t total_virtual_size = 0;
    258   size_t total_working_set_size = 0;
    259 #if defined(OS_WIN)
    260   size_t browser_peak_virtual_size = 0;
    261   size_t browser_peak_working_set_size = 0;
    262   size_t renderer_total_peak_virtual_size = 0;
    263   size_t renderer_total_peak_working_set_size = 0;
    264   size_t renderer_single_peak_virtual_size = 0;
    265   size_t renderer_single_peak_working_set_size = 0;
    266 #endif
    267 
    268   std::string output;
    269   ChromeProcessList::const_iterator it;
    270   for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
    271     base::ProcessHandle process_handle;
    272     if (!base::OpenProcessHandle(*it, &process_handle)) {
    273       NOTREACHED();
    274       return output;
    275     }
    276 
    277     // TODO(sgk):  if/when base::ProcessMetrics returns real stats on mac:
    278     // scoped_ptr<base::ProcessMetrics> process_metrics(
    279     //     base::ProcessMetrics::CreateProcessMetrics(process_handle));
    280     scoped_ptr<ChromeTestProcessMetrics> process_metrics(
    281         ChromeTestProcessMetrics::CreateProcessMetrics(process_handle));
    282 
    283     size_t current_virtual_size = process_metrics->GetPagefileUsage();
    284     size_t current_working_set_size = process_metrics->GetWorkingSetSize();
    285 
    286     if (*it == browser_pid) {
    287       browser_virtual_size = current_virtual_size;
    288       browser_working_set_size = current_working_set_size;
    289     } else {
    290       renderer_virtual_size += current_virtual_size;
    291       renderer_working_set_size += current_working_set_size;
    292     }
    293     total_virtual_size += current_virtual_size;
    294     total_working_set_size += current_working_set_size;
    295 
    296 #if defined(OS_WIN)
    297     size_t peak_virtual_size = process_metrics->GetPeakPagefileUsage();
    298     size_t peak_working_set_size = process_metrics->GetPeakWorkingSetSize();
    299     if (*it == browser_pid) {
    300       browser_peak_virtual_size = peak_virtual_size;
    301       browser_peak_working_set_size = peak_working_set_size;
    302     } else {
    303       if (peak_virtual_size > renderer_single_peak_virtual_size) {
    304         renderer_single_peak_virtual_size = peak_virtual_size;
    305       }
    306       if (peak_working_set_size > renderer_single_peak_working_set_size) {
    307         renderer_single_peak_working_set_size = peak_working_set_size;
    308       }
    309       renderer_total_peak_virtual_size += peak_virtual_size;
    310       renderer_total_peak_working_set_size += peak_working_set_size;
    311     }
    312 #endif
    313 
    314     base::CloseProcessHandle(process_handle);
    315   }
    316 
    317   std::string trace_name(test_name);
    318 #if defined(OS_WIN)
    319   AppendResult(output, "vm_peak_b", "", "vm_pk_b" + trace_name,
    320                browser_peak_virtual_size, "bytes",
    321                false /* not important */);
    322   AppendResult(output, "ws_peak_b", "", "ws_pk_b" + trace_name,
    323                browser_peak_working_set_size, "bytes",
    324                false /* not important */);
    325   AppendResult(output, "vm_peak_r", "", "vm_pk_r" + trace_name,
    326                renderer_total_peak_virtual_size, "bytes",
    327                false /* not important */);
    328   AppendResult(output, "ws_peak_r", "", "ws_pk_r" + trace_name,
    329                renderer_total_peak_working_set_size, "bytes",
    330                false /* not important */);
    331   AppendResult(output, "vm_single_peak_r", "", "vm_spk_r" + trace_name,
    332                renderer_single_peak_virtual_size, "bytes",
    333                false /* not important */);
    334   AppendResult(output, "ws_single_peak_r", "", "ws_spk_r" + trace_name,
    335                renderer_single_peak_working_set_size, "bytes",
    336                false /* important */);
    337   AppendResult(output, "vm_final_b", "", "vm_f_b" + trace_name,
    338                browser_virtual_size, "bytes",
    339                false /* not important */);
    340   AppendResult(output, "ws_final_b", "", "ws_f_b" + trace_name,
    341                browser_working_set_size, "bytes",
    342                false /* not important */);
    343   AppendResult(output, "vm_final_r", "", "vm_f_r" + trace_name,
    344                renderer_virtual_size, "bytes",
    345                false /* not important */);
    346   AppendResult(output, "ws_final_r", "", "ws_f_r" + trace_name,
    347                renderer_working_set_size, "bytes",
    348                false /* not important */);
    349   AppendResult(output, "vm_final_t", "", "vm_f_t" + trace_name,
    350                total_virtual_size, "bytes",
    351                false /* not important */);
    352   AppendResult(output, "ws_final_t", "", "ws_f_t" + trace_name,
    353                total_working_set_size, "bytes",
    354                false /* not important */);
    355 #elif defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_ANDROID)
    356   AppendResult(output,
    357                "vm_size_final_b",
    358                std::string(),
    359                "vm_size_f_b" + trace_name,
    360                browser_virtual_size,
    361                "bytes",
    362                false /* not important */);
    363   AppendResult(output,
    364                "vm_rss_final_b",
    365                std::string(),
    366                "vm_rss_f_b" + trace_name,
    367                browser_working_set_size,
    368                "bytes",
    369                false /* not important */);
    370   AppendResult(output,
    371                "vm_size_final_r",
    372                std::string(),
    373                "vm_size_f_r" + trace_name,
    374                renderer_virtual_size,
    375                "bytes",
    376                false /* not important */);
    377   AppendResult(output,
    378                "vm_rss_final_r",
    379                std::string(),
    380                "vm_rss_f_r" + trace_name,
    381                renderer_working_set_size,
    382                "bytes",
    383                false /* not important */);
    384   AppendResult(output,
    385                "vm_size_final_t",
    386                std::string(),
    387                "vm_size_f_t" + trace_name,
    388                total_virtual_size,
    389                "bytes",
    390                false /* not important */);
    391   AppendResult(output,
    392                "vm_rss_final_t",
    393                std::string(),
    394                "vm_rss_f_t" + trace_name,
    395                total_working_set_size,
    396                "bytes",
    397                false /* not important */);
    398 #else
    399   NOTIMPLEMENTED();
    400 #endif
    401   AppendResult(output,
    402                "processes",
    403                std::string(),
    404                "proc_" + trace_name,
    405                chrome_processes.size(),
    406                "count",
    407                false /* not important */);
    408 
    409   return output;
    410 }
    411 
    412 }  // namespace perf_test
    413