To see how this will benefit realtime related programming, I wrote a little benchmark. The code basically tries to wake up every 1/85 seconds and then measures the delay between ideal and actual wakeup time. The code was run once as a normal user, once as root with SCHED_FIFO scheduling. All values are in nanoseconds.
These are the results:
| 2.6.19rc6 vanilla | 2.6.20-hrt-dynticks1 | |||
| user | root (SCHED_FIFO) | user | root (SCHED_FIFO) | |
| min | 2809853 | 2331812 | 2939 | 2803 |
| max | 10877151 | 10091750 | 393117 | 226885 |
| avg | 6862276 | 6208266 | 37788 | 30500 |


As you can see, the latencies are greatly reduced. From a worst case of about 10 milliseconds without hrtimers to a worst case of about 0.4 milliseconds with the patch. The average latency even goes down from about 6 milliseconds to 0.04 milliseconds.
Here is the code (remember to compile with -lrt):
#include
#include
#include
#include
#include
#define FREQUENCY 85
#define PERIOD ( 1000000000 / FREQUENCY )
#define ITERATIONS ( FREQUENCY * 10 )
int64_t timespec_to_nsec( struct timespec* ts ) {
return (int64_t)ts->tv_sec * 1000000000LL + (int64_t)ts->tv_nsec;
}
int main( int argc, char** argv ) {
int err;
struct timespec t;
int i;
int64_t errors[ ITERATIONS ];
struct sched_param sp;
memset( &sp, 0, sizeof( sp ) );
sp.sched_priority = 99;
err = sched_setscheduler( getpid(), SCHED_FIFO, &sp );
if( err != 0 ) perror( "sched_setscheduler" );
err = clock_gettime( CLOCK_MONOTONIC, &t );
if( err != 0 ) { perror( "clock_gettime" ); exit( 1 ); }
for( i = 0; i < ITERATIONS; i++ ) {
struct timespec t2;
t.tv_nsec += PERIOD;
while( t.tv_nsec >= 1000000000 ) {
t.tv_sec += 1;
t.tv_nsec -= 1000000000;
}
err = clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &t, 0 );
if( err != 0 ) { perror( "clock_nanosleep" ); exit( 1 ); }
err = clock_gettime( CLOCK_MONOTONIC, &t2 );
if( err != 0 ) { perror( "clock_gettime" ); exit( 1 ); }
errors[ i ] = timespec_to_nsec( &t2 ) - timespec_to_nsec( &t );
}
int64_t min = 1000000000;
int64_t max = 0;
int64_t acc = 0;
for( i = 0; i < ITERATIONS; i++ ) {
int64_t e = errors[ i ];
printf( " %lld\n", e );
if( e > max ) max = e;
if( e < min ) min = e;
acc += e;
}
acc /= ITERATIONS;
printf( "min: %lld\n", min );
printf( "max: %lld\n", max );
printf( "avg: %lld\n", acc );
return 0;
}
0 comments:
Post a Comment