Search Wiki:

API


This page defines the public API for Scenario. See Examples for code examples that use this API, ETW Format for how Scenario fields are written to ETW events, and Best Practices for some thoughts about the best way to use Scenarios. The C++ definitions can also be found in the header file Scenario.h.

Typical Usage and Semantics


A typical usage case is to create a Scenario object, call its Begin method, then the code you want to benchmark, and finally the Scenario object's End method. Subsequently you may either check the elapsed time and CPU using the Elapsed and ElapsedCpu properties, or just rely on these properties having been logged to an ETW session. Once started, a Scenario measures both elapsed time and thread-level CPU consumption until it is stopped or reset. You may restart the Scenario after it has stopped simply by calling the Start method again. If you do so, it will resume measuring from the current elapsed time and CPU values. On the other hand, if you want to clear these values, use the Reset method before calling Start. Starting a Scenario that is already running, or stopping one that is already stopped, does not change the timer state or reset the elapsed time and CPU cycle count properties.

Methods


Constructors. There are five flavors of constructor, allowing the Size and Category properties to be set, and either a parent Scenario to be passed in when creating a nested child Scenario, or the nesting level to be set directly (see later). The C++ version uses default arguments to condense four of these into a single prototype.

// C#
    public Scenario()
    public Scenario(long size)
    public Scenario(long size, string category)
    public Scenario(long size, string category, Scenario parent)
    public Scenario(long size, string category, int nestingLevel)
 
// C++
    Scenario(LONG64 size = 0, LPCWSTR category = NULL, const Scenario* parent = NULL);
    Scenario(LONG64 size, LPCWSTR category, LONG nestingLevel);

Reset() resets the Scenario so that it can be re-used. The Category, Size, Elapsed, and ElapsedCpu fields are reset, and the timer is stopped.

// C#
    public void Reset()
 
// C++
    void Reset();

Begin() starts the Scenario's timer. The Size and Category properties can optionally be set at the same time. When ETW tracing is enabled, it generates an ETW "Begin" event with a default trace level of 5. Starting a Scenario that is already running does not change its timer state, reset its elapsed time and CPU properties, or increment its SequenceNumber.

// C#
    public void Begin()
    public void Begin(long size)
    public void Begin(long size, string category)
 
// C++
    void Begin();
    void Begin(LONG64 size);
    void Begin(LONG64 size, LPCWSTR category);

End() stops the Scenario's timer. The Size and Category properties can optionally be set at the same time. When ETW tracing is enabled, it generates an ETW "End" trace event with a default trace level of 4. Stopping a Scenario that is not running does not change the timer state or reset the elapsed time or CPU properties.

// C#
    public void End()
    public void End(long size)
    public void End(long size, string category)
 
// C++
    void End();
    void End(LONG64 size);
    void End(LONG64 size, LPCWSTR category);

Step() can be used to generate an intermediate timing event between calls to Begin() and End(). The Size and Category properties can optionally be set at the same time. When ETW tracing is enabled, it generates an ETW "Step" trace event with a default trace level of 5.

// C#
    public void End()
    public void End(long size)
    public void End(long size, string category)
 
// C++
    void End();
    void End(LONG64 size);
    void End(LONG64 size, LPCWSTR category);

BeginNew() is equivalent to a call to the Scenario instance constructor, followed by a call to Begin(). This follows the usage pattern of the Stopwatch class, and can be used to create a new instance of Scenario and start its timer functions immediately.

// C#
    public static Scenario BeginNew()
    public static Scenario BeginNew(long size)
    public static Scenario BeginNew(long size, string category)
    public static Scenario BeginNew(long size, string category, Scenario parent)
    public static Scenario BeginNew(long size, string category, int nestingLevel)

Mark() is used to generate stateless timing events without creating a Scenario object. The Size and Category properties of the event can optionally be set at the same time. When ETW tracing is enabled, it generates an ETW "Mark" event with a default trace level of 5.

// C#
    public static void Mark()
    public static void Mark(long size)
    public static void Mark(long size, string category)
 
// C++
    static void Mark(LONG64 size = 0, LPCWSTR category = NULL);

Information Properties


The following properties are available from a Scenario object or class, as appropriate, but are not written to ETW traces.

IsRunning. A read-only boolean value that indicates whether the Scenario's timer is running. True after a call to Begin(), false after a call to End() or Reset().

// C#
    public bool IsRunning
 
// C++
    bool IsRunning() const;

ThreadSwitchOccurred. A read-only boolean value that is true if the Scenario detects that it has been called from a different thread than it was created on. In these circumstances the elapsed thread-level CPU times are not valid, and are reset to 0.

// C#
    public bool ThreadSwitchOccurred
 
// C++
    bool ThreadSwitchOccurred() const;

HasElapsedCpu. A read-only static boolean value that indicates whether MeasurementBlocks will record elapsed thread-level CPU time. If this value is false (as it will be on Windows XP and below), then all calls to ElapsedCpu will return 0 (see also Data Properties, below).

// C#
    public static bool HasElapsedCpu
 
// C++
    static bool HasElapsedCpu();

Guid. A read-only static GUID value that contains the Scenario ETW provider GUID ({FB9244C9-F23A-4966-8A9C-97A51F8C355B}).

// C#
    public static Guid Guid
 
// C++
    static const GUID Guid;

Name. A read-only static string that contains the Scenario ETW provider name ("Scenario").

// C#
    public static string Name
 
// C++
    static const LPCWSTR Name;

Data Properties


The following data properties are also written to the payload of ETW trace events generated by Scenario objects. For details of the format in which they are written, see ETW Format.

Category. A read/write string that can be used to further characterize what's being measured, for example by naming the test. It can be initialized as part of a constructor call, as part of a call to the Begin(), Step(), or End() methods, or set explicitly. In the C# version, it defaults to the location in the code where the Scenario method was called. The string is limited to 127 Unicode characters.

// C#
    public string Category
 
// C++
    LPCWSTR GetCategory() const;
    void SetCategory(LPCWSTR newCategory);

ComponentId. A read/write 32-bit signed integer that can be used to further characterize what's being measured. It can only be set explicitly.

// C#
    public int ComponentId
 
// C++
    LONG GetComponentId() const;
    void SetComponentId(LONG newId);

CorrelationId. A read-only GUID identifying the Scenario instance.

// C#
     public Guid CorrelationId
 
// C++
    GUID GetCorrelationId() const;

Elapsed. A read-only value holding the elapsed time since Begin() was last called. It is reset to zero by a call to Reset(). In C# it is a TimeSpan. In C++ it is a number of DateTime "ticks", each of which is 100 nanoseconds (0.1 microseconds).

// C#
    public TimeSpan Elapsed
 
// C++
    ULONG64 GetElapsedTime();

ElapsedCpu. A read-only value holding the thread CPU consumption since Begin() was last called. It is not available on Windows XP. It is reset to zero by a call to Reset(). In C# it is a TimeSpan. In C++ it is a number of DateTime "ticks", each of which is 100 nanoseconds (0.1 microseconds). Note that CPU time is only recorded for the thread on which the Scenario was started, not for all threads of a process.

// C#
    public TimeSpan ElapsedCpu
 
// C++
    ULONG64 GetElapsedCpu();

NestingLevel. A read-only 32-bit integer holding the level to which this Scenario is nested (0 if not nested). It can be initialized as part of a constructor call.

// C#
    public int NestingLevel
 
// C++
    LONG GetNestingLevel() const;

ParentCorrelationId. A read-only GUID identifying the parent of this Scenario instance. Guid.Empty if this instance has no parent.

// C#
    public Guid ParentCorrelationId
 
// C++
    GUID GetParentCorrelationId() const;

ParentSequenceNumber. A read-only 32-bit integer holding the number of times that the parent Scenario had been started when this Scenario was created. 0 if this instance has no parent.

// C#
    public int ParentSequenceNumber
 
// C++
    LONG GetParentSequenceNumber() const;

SequenceNumber. A read-only 32-bit integer holding the number of times that this instance has been started.

// C#
    public int SequenceNumber
 
// C++
    LONG GetSequenceNumber() const;

Size. A read/write 64-bit integer that can be set by the user to further characterize what's being measured. For example, it can be used to record the size of a file being processed, the size of a message being handled, or some other quantitative information. It can be initialized as part of a constructor call, as part of a call to the Begin(), Step(), or End() methods, or set explicitly. It is reset to 0 by a call to Reset().

// C#
    public long Size
 
// C++
    LONG64 GetSize() const;
    void SetSize(LONG64 newSize);

Trace Levels and Nesting


Scenarios can be nested to any arbitrary depth to indicate the structure and flow of the functions you are measuring. To nest Scenarios, you pass a parent Scenario to the constructor of the child Scenario:

    Scenario globalTimer = new Scenario();
    ...
    Scenario functionTimer = new Scenario(size, "Nested function", globaltimer);

The nesting level can also be set directly as part of a constructor call. Note that it is not an error if a parent Scenario goes out of scope prior to the child Scenario. However, because this situation is logically inconsistent it should be avoided wherever possible, to avoid problems of interpretation later.

This nesting information is reflected in ETW trace levels. By default, End events are level 4 informational events, while those emitted by Begin, Step, and Mark are level 5 diagnostic events. These levels are increased by one for each successive level of nesting. An ETW controller can then be used to select the level of events to log. Here is an example using XPerf to log only non-nested End events:

    xperf -start OnlyEndEvents -on "ScenarioProvider::4" -f OnlyEndEvents.etl
Last edited Oct 12 2009 at 3:55 AM  by JonathanH, version 7
Updating...
Page view tracker