PerfMeasurement.jsm

  • Revision slug: JavaScript_code_modules/PerfMeasurement.jsm
  • Revision title: PerfMeasurement.jsm
  • Revision id: 97466
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment 236 words added, 126 words removed

Revision Content

{{ gecko_minversion_header("2.0") }}

The PerfMeasurement.jsm JavaScript code module lets you take detailed performance measurements of your code.

{{ note("The PerfMeasurement.jsm JavaScript code module can only be used from chrome -- that is, from within the application itself or an add-on.") }}

Before you can use this module, you need to import it into your scope:

Components.utils.import("resource://gre/modules/PerfMeasurement.jsm")

You can then create a PerfMeasurement object. You give the constructor a bit-mask of events you're interested in.

Note: At present, PerfMeasurement.jsm is only functional on Linux, but it is planned to add support for Windows ({{ Bug("583322") }}) and OSX ({{ Bug("583323") }}) as well, and we welcome patches for other operating systems.

For instance, let's measure instructions executed, cache references, and cache misses:

let monitor = new PerfMeasurement(PerfMeasurement.CPU_CYCLES | PerfMeasurement.CACHE_REFERENCES | PerfMeasurement.CACHE_MISSES);

This just sets up to measure stuff, it doesn't start timing anything.  Now, we want to benchmark a function that is pretty fast (but not fast enough), so we run it several thousand times:

for (let i = 0; i < 10000; i++) {
  set_up_some_state();
  monitor.start();
  code_to_be_benchmarked();
  monitor.stop();
  clean_up_afterward();
}

Only the work done by code_to_be_benchmarked(), not set_up_some_state() or clean_up_afterward(), will be measured.  The monitor object automatically accumulates counts over start/stop cycles.  When you're done benchmarking, you can read out each of the counters you asked for as properties:

let report = "CPU cycles:   " + monitor.cpu_cycles + "\n" +
             "Cache refs:   " + monitor.cache_references + "\n" +
             "Cache misses: " + monitor.cache_misses + "\n";
monitor.reset();
alert(report);

The reset method clears all of the enabled counters, as you might expect.  When you're done with your measurements, just let the monitor object go out of scope.

For more details, including a complete list of events that can be measured, see the C++ documentation.

Method overview

void reset();
void start();
void stop();

Member variables

These variables provide access to the recorded data. Any measurable event that was not being recorded has a value of -1 (that is, 0xFFFFFFFFFFFFFFFF).

Variable Type Description
cpu_cycles uint64
The number of CPU cycles elapsed.
instructions
uint64
The number of instructions executed.
cache_references
uint64
The number of cache references that occurred.
cache_misses
uint64
The number of times cache references missed.
branch_instructions
uint64
The number of branch instructions executed.
branch_misses
uint64
The number of times branch prediction guessed wrong.
bus_cycles
uint64
The number of bus cycles that elapsed.
page_faults
uint64
The number of page faults that occurred.
major_page_faults
uint64
The number of major page faults that occurred.
context_switches
uint64
The number of context switches that occurred.
cpu_migrations
uint64
The number of times the thread switched CPUs.

Constants

Event mask constants

These constants are used to construct the mask indicating which events you want to monitor.

Constant Value Description
CPU_CYCLES 0x00000001 Measure CPU cycles elapsed.
INSTRUCTIONS 0x00000002 Measure the number of instructions executed.
CACHE_REFERENCES 0x00000004 Measure the number of cache references.
CACHE_MISSES 0x00000008 Measure the number of cache misses.
BRANCH_INSTRUCTIONS 0x00000010 Measure the number of branch instructions executed.
BRANCH_MISSES 0x00000020 Measure the number of times branch prediction guesses wrong.
BUS_CYCLES 0x00000040 Measure the number of bus cycles elapsed.
PAGE_FAULTS 0x00000080 Measure the number of page faults that occurred.
MAJOR_PAGE_FAULTS 0x00000100 Measure the number of major page faults that occurred.
CONTEXT_SWITCHES 0x00000200 Measure the number of context switches that occurred.
CPU_MIGRATIONS 0x00000400 Measure the number of context switches that occurred.
ALL 0x000007FF Measure all available events.

Methods

reset()

Resets all the enabled counters to zero.

void reset();
Parameters

None.

start()

Starts measuring the performance indicators that were specified when the PerfMeasurement object was created.

void start();
Parameters

None.

stop()

Stops measuring performance data. For each enabled counter, the number of measured events of that type that occurred are added to the appropriate visible variable.

void stop();
Parameters

None.

Revision Source

<p>{{ gecko_minversion_header("2.0") }}</p>
<p><code>The PerfMeasurement.jsm</code> JavaScript code module lets you take detailed performance measurements of your code.</p>
<p>{{ note("The <code>PerfMeasurement.jsm</code> JavaScript code module can only be used from chrome -- that is, from within the application itself or an add-on.") }}</p>
<p>Before you can use this module, you need to import it into your scope:</p>
<pre><span class="plain">Components.utils.import("resource://gre/modules/PerfMeasurement.jsm")</span></pre>
<p>You can then create a <code>PerfMeasurement</code> object. You give the constructor a bit-mask of events you're interested in.</p>
<div class="note"><strong>Note:</strong> At present, <code>PerfMeasurement.jsm</code> is only functional on Linux, but it is planned to add support for Windows ({{ Bug("583322") }}) and OSX ({{ Bug("583323") }}) as well, and we welcome patches for other operating systems.</div>
<p>For instance, let's measure instructions executed, cache references, and cache misses:</p>
<pre class="brush: js"><span class="nowiki">let monitor = new PerfMeasurement(PerfMeasurement.CPU_CYCLES | PerfMeasurement.CACHE_REFERENCES | PerfMeasurement.CACHE_MISSES);</span></pre>
<p>This just sets up to measure stuff, it doesn't start timing anything.  Now, we want to benchmark a function that is pretty fast (but not fast enough), so we run it several thousand times:</p>
<pre class="brush: js">for (let i = 0; i &lt; 10000; i++) {
  set_up_some_state();
  monitor.start();
  code_to_be_benchmarked();
  monitor.stop();
  clean_up_afterward();
}
</pre>
<p>Only the work done by <code>code_to_be_benchmarked()</code>, not <code>set_up_some_state()</code> or <code>clean_up_afterward()</code>, will be measured.  The <code>monitor</code> object automatically accumulates counts over start/stop cycles.  When you're done benchmarking, you can read out each of the counters you asked for as properties:</p>
<pre class="brush: js">let report = "CPU cycles:   " + monitor.cpu_cycles + "\n" +
             "Cache refs:   " + monitor.cache_references + "\n" +
             "Cache misses: " + monitor.cache_misses + "\n";
monitor.reset();
alert(report);
</pre>
<p>The <code>reset</code> method clears all of the enabled counters, as you might expect.  When you're done with your measurements, just let the <code>monitor</code> object go out of scope.</p>
<p>For more details, including a complete list of events that can be measured, see the <a href="/en/JS::PerfMeasurement" title="en/JS::PerfMeasurement">C++ documentation</a>.</p>
<h2>Method overview</h2>
<table class="standard-table"> <tbody> <tr> <td><code>void <a href="/en/JavaScript_code_modules/PerfMeasurement.jsm#reset()" title="en/JavaScript code modules/PerfMeasurement.jsm#reset()">reset</a>();<br> </code></td> </tr> <tr> <td><code>void <a href="/en/JavaScript_code_modules/PerfMeasurement.jsm#start()" title="en/JavaScript code modules/PerfMeasurement.jsm#start()">start</a>();<br> </code></td> </tr> <tr> <td><code>void <a href="/en/JavaScript_code_modules/PerfMeasurement.jsm#stop()" title="en/JavaScript code modules/PerfMeasurement.jsm#stop()">stop</a>();<br> </code></td> </tr> </tbody>
</table>
<h2>Member variables</h2>
<p>These variables provide access to the recorded data. Any measurable event that was not being recorded has a value of -1 (that is, 0xFFFFFFFFFFFFFFFF).</p>
<table class="standard-table"> <tbody> <tr> <td class="header">Variable</td> <td class="header">Type</td> <td class="header">Description</td> </tr> <tr> <td><code>cpu_cycles</code></td> <td><code>uint64<br> </code></td> <td>The number of CPU cycles elapsed.</td> </tr> <tr> <td><code>instructions<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of instructions executed.</td> </tr> <tr> <td><code>cache_references<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of cache references that occurred.</td> </tr> <tr> <td><code>cache_misses<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of times cache references missed.</td> </tr> <tr> <td><code>branch_instructions<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of branch instructions executed.</td> </tr> <tr> <td><code>branch_misses<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of times branch prediction guessed wrong.</td> </tr> <tr> <td><code>bus_cycles<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of bus cycles that elapsed.</td> </tr> <tr> <td><code>page_faults<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of page faults that occurred.</td> </tr> <tr> <td><code>major_page_faults<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of major page faults that occurred.</td> </tr> <tr> <td><code>context_switches<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of context switches that occurred.</td> </tr> <tr> <td><code>cpu_migrations<br> </code></td> <td><code>uint64<br> </code></td> <td>The number of times the thread switched CPUs.</td> </tr> </tbody>
</table>
<h2>Constants</h2>
<h3>Event mask constants</h3>
<p>These constants are used to construct the mask indicating which events you want to monitor.</p>
<table class="standard-table"> <tbody>  <tr> <td class="header">Constant</td> <td class="header">Value</td> <td class="header">Description</td> </tr> <tr> <td>CPU_CYCLES</td> <td><code>0x00000001</code></td> <td>Measure CPU cycles elapsed.</td> </tr> <tr> <td>INSTRUCTIONS</td> <td>0x00000002</td> <td>Measure the number of instructions executed.</td> </tr> <tr> <td>CACHE_REFERENCES</td> <td>0x00000004</td> <td>Measure the number of cache references.</td> </tr> <tr> <td>CACHE_MISSES</td> <td>0x00000008</td> <td>Measure the number of cache misses.</td> </tr> <tr> <td>BRANCH_INSTRUCTIONS</td> <td>0x00000010</td> <td>Measure the number of branch instructions executed.</td> </tr> <tr> <td>BRANCH_MISSES</td> <td>0x00000020</td> <td>Measure the number of times branch prediction guesses wrong.</td> </tr> <tr> <td>BUS_CYCLES</td> <td>0x00000040</td> <td>Measure the number of bus cycles elapsed.</td> </tr> <tr> <td>PAGE_FAULTS</td> <td>0x00000080</td> <td>Measure the number of page faults that occurred.</td> </tr> <tr> <td>MAJOR_PAGE_FAULTS</td> <td>0x00000100</td> <td>Measure the number of major page faults that occurred.</td> </tr> <tr> <td>CONTEXT_SWITCHES</td> <td>0x00000200</td> <td>Measure the number of context switches that occurred.</td> </tr> <tr> <td>CPU_MIGRATIONS</td> <td>0x00000400</td> <td>Measure the number of context switches that occurred.</td> </tr> <tr> <td>ALL</td> <td>0x000007FF</td> <td>Measure all available events.</td> </tr> </tbody>
</table>
<h2>Methods</h2>
<h3>reset()</h3>
<p>Resets all the enabled counters to zero.</p>
<pre>void reset();
</pre>
<h6>Parameters</h6>
<p>None.</p>
<h3>start()</h3>
<p>Starts measuring the performance indicators that were specified when the <code>PerfMeasurement</code> object was created.</p>
<pre>void start();
</pre>
<h6>Parameters</h6>
<p>None.</p>
<h3>stop()</h3>
<p>Stops measuring performance data. For each enabled counter, the number of measured events of that type that occurred are added to the appropriate visible variable.</p>
<pre>void stop();
</pre>
<h6>Parameters</h6>
<p>None.</p>
Revert to this revision