The overhead of compiler-based instruction can be very high, particularly for code with high floating-point arithmetic intensity. We provide annotations as a method to control (and hopefully reduce) the instrumentation overhead.
When a particular code region is annotated, the instrumentation only occurs in the annotated region, instead of in the entire application. We provide two levels for annotations: function and basic block annotations.
When code is annotated, the FPC_ANNOTATED
variable must be set.
Function Annotations
To annotate a function, add FPC_INSTRUMENT_FUNC
macro to the definition of a function. For example:
FPC_INSTRUMENT_FUNC
double my_function(double *x, int size) {
...
...
}
Basic Block Annotations
To annotate a basic block of code, add FPC_INSTRUMENT_BLOCK
macro to the begininng of the target basic block. For example:
double my_function(double *x, int size) {
// Annotated basic block
FPC_INSTRUMENT_BLOCK;
double tmp = x[0] + 1.23;
x[1] = tmp / 2.0;
// For loop
for (int i=0; ...) {
// This block is not annotated
...
}
}
These macros are defined in Runtime_cpu.h
as:
#define FPC_INSTRUMENT_BLOCK __attribute__((annotate("_FPC_INSTRUMENT_BLOCK_"))) int _marker __attribute__((unused)) = 0;
#define FPC_INSTRUMENT_FUNC __attribute__((annotate("_FPC_INSTRUMENT_FUNCTION_")))