mirror of https://github.com/ipxe/ipxe.git
[profile] Provide methods for profiling individual stages of operations
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/19/head
parent
bcfaf119a7
commit
a0da06c306
|
@ -51,7 +51,8 @@ static struct profiler r2p_profiler __profiler = { .name = "r2p" };
|
||||||
*/
|
*/
|
||||||
static void librm_test_exec ( void ) {
|
static void librm_test_exec ( void ) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned long p2r_elapsed;
|
unsigned long timestamp;
|
||||||
|
unsigned int discard_d;
|
||||||
|
|
||||||
/* Profile mode transitions. We want to profile each
|
/* Profile mode transitions. We want to profile each
|
||||||
* direction of the transition separately, so perform an RDTSC
|
* direction of the transition separately, so perform an RDTSC
|
||||||
|
@ -61,10 +62,11 @@ static void librm_test_exec ( void ) {
|
||||||
for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
|
for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
|
||||||
profile_start ( &p2r_profiler );
|
profile_start ( &p2r_profiler );
|
||||||
__asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
|
__asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
|
||||||
: "=A" ( r2p_profiler.started ) : );
|
: "=a" ( timestamp ), "=d" ( discard_d )
|
||||||
|
: );
|
||||||
|
profile_start_at ( &r2p_profiler, timestamp );
|
||||||
profile_stop ( &r2p_profiler );
|
profile_stop ( &r2p_profiler );
|
||||||
p2r_elapsed = ( r2p_profiler.started - p2r_profiler.started );
|
profile_stop_at ( &p2r_profiler, timestamp );
|
||||||
profile_update ( &p2r_profiler, p2r_elapsed );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER );
|
FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <bits/profile.h>
|
#include <bits/profile.h>
|
||||||
#include <ipxe/tables.h>
|
#include <ipxe/tables.h>
|
||||||
|
|
||||||
|
@ -26,7 +25,9 @@ struct profiler {
|
||||||
/** Name */
|
/** Name */
|
||||||
const char *name;
|
const char *name;
|
||||||
/** Start timestamp */
|
/** Start timestamp */
|
||||||
uint64_t started;
|
unsigned long started;
|
||||||
|
/** Stop timestamp */
|
||||||
|
unsigned long stopped;
|
||||||
/** Number of samples */
|
/** Number of samples */
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
/** Mean sample value (scaled) */
|
/** Mean sample value (scaled) */
|
||||||
|
@ -62,6 +63,20 @@ extern unsigned long profile_mean ( struct profiler *profiler );
|
||||||
extern unsigned long profile_variance ( struct profiler *profiler );
|
extern unsigned long profile_variance ( struct profiler *profiler );
|
||||||
extern unsigned long profile_stddev ( struct profiler *profiler );
|
extern unsigned long profile_stddev ( struct profiler *profiler );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start profiling
|
||||||
|
*
|
||||||
|
* @v profiler Profiler
|
||||||
|
* @v started Start timestamp
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) void
|
||||||
|
profile_start_at ( struct profiler *profiler, unsigned long started ) {
|
||||||
|
|
||||||
|
/* If profiling is active then record start timestamp */
|
||||||
|
if ( PROFILING )
|
||||||
|
profiler->started = started;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start profiling
|
* Start profiling
|
||||||
*
|
*
|
||||||
|
@ -72,7 +87,23 @@ profile_start ( struct profiler *profiler ) {
|
||||||
|
|
||||||
/* If profiling is active then record start timestamp */
|
/* If profiling is active then record start timestamp */
|
||||||
if ( PROFILING )
|
if ( PROFILING )
|
||||||
profiler->started = profile_timestamp();
|
profile_start_at ( profiler, profile_timestamp() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record profiling result
|
||||||
|
*
|
||||||
|
* @v profiler Profiler
|
||||||
|
* @v stopped Stop timestamp
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) void
|
||||||
|
profile_stop_at ( struct profiler *profiler, unsigned long stopped ) {
|
||||||
|
|
||||||
|
/* If profiling is active then record end timestamp and update stats */
|
||||||
|
if ( PROFILING ) {
|
||||||
|
profiler->stopped = stopped;
|
||||||
|
profile_update ( profiler, ( stopped - profiler->started ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,13 +113,10 @@ profile_start ( struct profiler *profiler ) {
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) void
|
static inline __attribute__ (( always_inline )) void
|
||||||
profile_stop ( struct profiler *profiler ) {
|
profile_stop ( struct profiler *profiler ) {
|
||||||
uint64_t ended;
|
|
||||||
|
|
||||||
/* If profiling is active then record end timestamp and update stats */
|
/* If profiling is active then record end timestamp and update stats */
|
||||||
if ( PROFILING ) {
|
if ( PROFILING )
|
||||||
ended = profile_timestamp();
|
profile_stop_at ( profiler, profile_timestamp() );
|
||||||
profile_update ( profiler, ( ended - profiler->started ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _IPXE_PROFILE_H */
|
#endif /* _IPXE_PROFILE_H */
|
||||||
|
|
Loading…
Reference in New Issue