Refining Timing Results

There are cases where the tool is unable to fully determine the timing of a section of code, due to, for example, not being able to determine a loop count. This can be addressed by adding defines. Defines can be added in two ways, to a global list, or to a route-specific list. Those added to the global list get applied to every route when upon creation.

The use of the global list can result in more concise scripts. However, It is important to be careful with defines added to the global list since they are ignored if they fail to get applied to a route. This allows a full set of defines to be created before any routes, but does mean that errors in these defines might be missed. Route specific defines (added post route creation) will always flag an error if there is one.

Exclusions

Not all paths of execution in a route may be timing-critical. The route may contain cases to handle errors where the timing of the code is not important. These paths can be ignored in the timing script by adding exclusions. Exclusions tell the tool to ignore all paths which pass through that code point. Exclusions can be added to the global list or applied to a specific route.

In xTIMEcomposer Studio, to set an exclusion on an existing route, right click within the relevant path and select Exclude. This can be done in the editor, the lower panel of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set exclusion <route id> <ANY>

To add an exclusion to the list of exclusions to be taken into account during route creation, right click within the relevant path and select Add to exclusion list. This can be done on the vertical ruler of the text editor, in the Disassembly View, the lower panel of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

add exclusion <ANY>

The current global list of exclusions can be found in the Exclusions section of the Info View.

On the console, type:

list exclusions

To remove an exclusion from the global list, find the relevant exclusion in the Info View, right click and choose Remove or press Delete.

On the console, type:

remove exclusion <ANY|*>

For example, consider the code in Excluding an invalid path.

Excluding an invalid path
int calculate ( int a, int b) {
    if ( willOverflow (a, b) {
        # pragma xta label " overflow "
        return processOverflow ();
    }
    return a + b;
}

To time the calculate function ignoring the error case:

  • Using route-specific defines:
    • analyze function calculate
    • set exclusion - overflow
  • Using global defines:
    • add exclusion overflow
    • analyze function calculate

Although functionally equivalent, exclusion via the global defines mechanism can result in faster, and more memory efficient, route creation. This is because the global exclusions can be taken into account during route creation, so the search space can be reduced. For post route creation exclusions, the complete route is created before any pruning occurs.

Loop Iterations

Loop iteration counts can be unknown. Whenever possible, the compiler tells the tool about loop iteration counts. However, some loop counts are not known statically. In these cases the user is required to specify worst-case values.

The compiler does not emit any loop iteration counts unless optimizations have been enabled (-O1 or greater).

Some loops are self loops (loops whose body is the same as the header) and therefore have a minimum iteration count of 1.

In xTIMEcomposer Studio, to set loop iterations on an existing route, right click within the body of the loop, but not within an inner loop, and select Set loop iterations. This can be done on the vertical ruler of the text editor, in the Disassembly View, the lower pane of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set loop <route id> <ANY> <iterations>

To add an iteration count to the list of iteration counts to be used during route creation, click the Add Define button in the toolbar, and select the Loop tab.

On the console, type:

add loop <ANY> <iterations>

The current list of global loop iteration counts can be found in the defines section of the Info View.

On the console, type:

list loops

To remove a loop iteration count from the global list, find the relevant entry in the Info View, right click and choose Remove or press Delete.

On the console, type:

remove loop <ANY|*>

For example, consider the code in Setting loop iterations..

Setting loop iterations.
void delay ( int j) {
    for ( unsigned int i = 0; i < j; ++i) {
        # pragma xta label " delay_loop "
        delay_us (1);
    }
}

int test () {
    delay (10);
}

To time the test function:

  • Using route-specific defines:
    • analyze function test
    • set loop - delay_loop 10
  • Using global defines:
    • add loop delay_loop 10
    • analyze function test

Loop Path Iterations

A loop may contain multiple paths through it. When a loop iteration count has been set the tools assumes that all iterations will take the worst-case path of execution through the loop. This is not always the case, and a more realistic worst-case can be established by specifying the number of iterations on individual paths through the loop.

To set loop path iterations on an existing route, right click on a path within the body of the loop, and select Set loop path iterations. This can be done on the vertical ruler of the text editor, in the Disassembly View, the lower pane of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set looppath <route id> <ANY> <iterations>

To add a loop path count to the list of loop path counts to be used during route creation, click the Add Define button in the toolbar, and select the Loop path tab.

On the console, type:

add looppath <ANY> <iterations>

The current list of global loop path counts can be found in the defines section of the Info View.

On the console, type:

list looppaths

To remove a loop path count from the global list, find the relevant entry in the Info View, right click and choose Remove or press Delete.

On the console, type:

remove looppath <ANY|*>

There are some rules that need to be followed when setting loop path iterations:

  • In a nested loop, the outer loop iterations need to be set first.
  • The loop path iterations set must be less than or equal to the loop iterations set on the enclosing loop.
  • If the loop path iterations set are less than that of the enclosing loop, then there must exist another path within the loop without its iterations set to which the remaining iterations can be allocated.

For example, consider the code in Setting loop path iterations.:

Setting loop path iterations.
void f( int j) {
    for ( unsigned int i = 0; i < j; ++i) {
        # pragma xta label " f_loop "
        if ((i & 1) == 0) {
            # pragma xta label " f_if "
            g ();
        }
    }
}

int test () {
    f (10);
}

To time the test function:

  • Using route-specific defines:
    • analyze function test
    • set loop - f_loop 10
    • set looppath - f_if 5
  • Using global defines:
    • add loop f_loop 10
    • add looppath f_if 5
    • analyze function test

Loop Scope

By default, the tool assumes that the iterations for loops are relative—the iterations for an inner loop will be multiplied by the iterations of enclosing loops. However this is not sufficient to describe all loop structures. If this assumption is not correct a loop count can be set to absolute. The iteration count set on an absolute loop is not multiplied up by the iterations set on enclosing loops.

To set loop scope on an existing route, right click within the body of the loop, and select Set loop scope. This can be done on the vertical ruler of the text editor, in the Disassembly View, the lower pane of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set loopscope <route id> <ANY> <absolute|relative>

To add a loop scope to the list of loop scopes to be used during route creation, click the Add Define button in the toolbar, and select the Loop scope tab.

On the console, type:

add loopscope <ANY> <absolute|relative>

The current list of global loop scopes can be found in the defines section of the Info View.

On the console, type:

list loopscopes

To remove a loop scope from the global list, find the relevant entry in the Info View, right click and choose Remove.

On the console, type:

remove loopscope <ANY|*>

For example, consider the code in Setting loop scope.

Setting loop scope.
void f( int l) {
    for ( unsigned int i = 0; i < l; ++i) {
        # pragma xta label " outer_loop "
        for ( unsigned int j = 0; j < i; ++j) {
            # pragma xta label " inner_loop "
            g ();
        }
    }
}

void test () {
    f (10);
}

To time the test function:

  • Using route-specific defines:
    • analyze function test
    • set loop - outer_loop 10
    • set loop - inner_loop 45
    • set loopscope - inner_loop absolute
  • Using global defines:
    • add loop outer_loop 10
    • add loop inner_loop 45
    • add loopscope inner_loop absolute
    • analyze function test

Instruction Times

Some instructions can pause the processor. By default, the tool reports timing assuming that no instructions pause, but flags them as warnings. The user must specify what the worst-case execution time of instructions are.

To set an instruction time in an existing route, right click on the instruction and select Set instruction time. This can be done on the vertical ruler of the text editor, in the Disassembly View, the lower pane of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set instructiontime <route id> <ENDPOINT> <value> <MODE>

To add an instruction time to the list of instruction times to be used during route creation, click the Add Define button in the toolbar, and select the Instruction time tab.

On the console, type:

add instructiontime <ENDPOINT> <value> <MODE>

The current list of global instruction times can be found in the defines section of the Info View.

On the console, type:

list instructiontimes

To remove an instruction time from the global list, find the relevant entry in the Info View, right click and choose Remove or press Delete.

On the console, type:

remove instructiontime <ANY|*>

For example, consider the code in Setting an instruction time..

Setting an instruction time.
void f( port p) {
    # pragma endpoint " instr "
    p :> value ;
}

To time the f function:

  • Using route-specific defines:
    • analyze function f
    • set instructiontime - instr 100.0 ns
  • Using global defines:
    • add instructiontime instr 100.0 ns
    • analyze function f

Function Times

In some cases it is necessary to define the time it takes to execute an entire function. The tool supports defining a function time. Once a function time is defined, all the unknowns within it are ignored and any routes which span this function will use the defined time instead of calculating it.

To set a function time on an existing route, right click on a function and select Set function time. This can be done in the the lower pane of the Routes View or the Structure tab of the Visualizations View.

On the console, type:

set functiontime <route id> <FUNCTION> <value> <MODE>

To add a function time to the list of function times to be used during route creation, click the Add Define button in the toolbar, and select the Function time tab.

On the console, type:

add functiontime <FUNCTION> <value> <MODE>

The current list of global function times can be found in the defines section of the Info View.

On the console, type:

list functiontimes

To remove an function time from the global list, find the relevant entry in the Info View, right click and choose Remove.

On the console, type:

remove functiontime <FUNCTION|*>

For example, consider the code in Setting a function time..

Setting a function time.
void delayOneSecond () {
    g ();
    }

void test () {
    delayOneSecond ();
}

To time the test function:

  • Using route-specific defines:
    • analyze function test
    • set functiontime - delayOneSecond 1000.0 ms
  • Using global defines:
    • add functiontime delayOneSecond 1000.0 ms
    • analyze function test

Path Times

In some cases it is necessary to define the time it takes to execute a particular section of code. The tool supports defining a path time for this case. Once a path time is defined all the unknowns within it are ignored, and any routes which span this section of code will use the defined time instead of calculating it.

To set a path time on an existing route, highlight the start and end nodes in the lower pane of the Routes View, right click and and select Set path time.

On the console, type:

set pathtime <route id> <from ENDPOINT> <to ENDPOINT> <value> <MODE>

To add a path time to the list of path times to be used during route creation, click the Add Define button in the toolbar, and select the Path time tab.

On the console, type:

add pathtime <from ENDPOINT> <to ENDPOINT> <value> <MODE>

The current list of global path times can be found in the defines section of the Info View.

On the console, type:

list pathtimes

To remove an path time from the global list, find the relevant entry in the Info View, right click and choose Remove.

On the console, type:

remove pathtime <from ENDPOINT|*> <to ENDPOINT|*>

For example, consider the code in Setting a path time..

Setting a path time.
int f() {
    int time ;
    timer t;
    # pragma xta endpoint " start "
    t :> time ;
    # pragma xta endpoint " stop "
    t when timerafter ( time + 100) :> time ;
}

void test () {
    f ();
}

To time the test function:

  • Using route-specific defines:
    • analyze function test
    • set pathtime - start stop 1000.0 ns
  • Using global defines:
    • add pathtime start stop 1000.0 ns
    • analyze function test

Active Tiles

By default the tool finds routes on all tiles within a program. However, it is possible to restrict the tool to work only on a subset of the tiles in the program. The set of tiles all commands apply to is called the active tiles.

In xTIMEcomposer Studio open the Timing Properties and select which tiles are active.

On the console, type:

  • add tile <tile id>
  • remove tile <tile id|*>
  • list tiles

Node Frequency

An XMOS device consists of a number of nodes, each one composed of a number of xCORE tiles. The frequency at which a node runs is defined in the binary and the tool reads this and configures the node frequencies when it loads the binary. It is possible to experiment to determine what will happen at different frequencies if desired.

In xTIMEcomposer Studio open the Timing Properties and change the frequency for the node to be changed.

On the console, type:

config freq <node id> <tile frequency>

Number Of Logical Cores

The maximum number of logical cores run on a tile is known at compile time and the tool extracts this information from the binary for each tile. It is possible to experiment to determine what will happen if running with a different number of cores if desired.

In xTIMEcomposer Studio open the Timing Properties and change the number of cores for the node/tile to be changed.

On the console, type:

config cores <tile id> <num cores>

See Also