Re: cpu consumption calculation - why these difference ?

Pavel Machek (pavel@bug.ucw.cz)
Sun, 23 May 1999 21:30:51 +0200


Hi!

> > I've got one question about how the cpu consumption is calculated.
> >
> > Bellow are two programs that do the same thing, play stuff to the soundcard.
> > The first uses a blocking write, the second a nonblocking one with a select.
> > The select does not block (if it did, the cpu consumption is reported to
> > be the same than the first method, both by ps and top). It does an
> > usleep(10*1000) if there is no space left in the audio buffers.
> >
> > My question is : why does the first get 5% of cpu consumption reported
> > by both ps and top when the second gets only 0.1% ? They both do the same
> > calculations, so it should be equal, nope ? Is it related to the kernel
> > or just the ps and top programs ? (Is it only a problem ?)
>
> Kernel cpu meters do not work too well, see may badboy examples and
> discussion around them. I even have patch, somewhere... Search archives.

Following up myself, anyway, here's the patch. Tell me if it makes a
difference.
Pavel

--- clean/kernel/sched.c Fri Mar 26 17:46:31 1999
+++ linux/kernel/sched.c Fri Mar 26 17:31:12 1999
@@ -78,6 +78,7 @@
long time_adjust = 0;
long time_adjust_step = 0;

+int need_update_times = 0;
unsigned long event = 0;

extern int do_setitimer(int, struct itimerval *, struct itimerval *);
@@ -98,6 +99,8 @@

struct kernel_stat kstat = { 0 };

+static void update_process_times(struct task_struct *p, unsigned long ticks, unsigned long system);
+
void scheduling_functions_start_here(void) { }

#ifdef __SMP__
@@ -767,17 +772,22 @@
next->has_cpu = 1;
spin_unlock(&scheduler_lock);
#endif /* __SMP__ */
- if (prev != next) {
+
+ if (need_update_times)
+ update_process_times( next, 1, 1 );
+
+ if (prev != next) {
#ifdef __SMP__
sched_data->prev = prev;
#endif
- kstat.context_swtch++;
+ kstat.context_swtch++;
+
get_mmu_context(next);
switch_to(prev,next);

__schedule_tail();
}
-
+
reacquire_kernel_lock(current);
return;

@@ -1357,14 +1367,15 @@
do_it_prof(p, ticks);
}

-static void update_process_times(unsigned long ticks, unsigned long system)
+static void update_process_times(struct task_struct *p, unsigned long ticks, unsigned long system)
{
/*
* SMP does this on a per-CPU basis elsewhere
*/
#ifndef __SMP__
- struct task_struct * p = current;
unsigned long user = ticks - system;
+ need_update_times = 0;
+
if (p->pid) {
p->counter -= ticks;
if (p->counter < 0) {
@@ -1410,8 +1421,11 @@
calc_load(ticks);
update_wall_time(ticks);
write_unlock_irq(&xtime_lock);
-
- update_process_times(ticks, system);
+
+ if (current->pid || (!current->need_resched))
+ update_process_times(current, ticks, system);
+ else
+ need_update_times = 1;

} else
write_unlock_irq(&xtime_lock);
@@ -1419,20 +1433,20 @@

static void timer_bh(void)
{
- update_times();
run_old_timers();
run_timer_list();
+ update_times();
}

void do_timer(struct pt_regs * regs)
{
- (*(unsigned long *)&jiffies)++;
+ (*(unsigned long *)&jiffies)++; /* Otherwise gcc will generate ugly code */
lost_ticks++;
- mark_bh(TIMER_BH);
if (!user_mode(regs))
lost_ticks_system++;
if (tq_timer)
mark_bh(TQUEUE_BH);
+ mark_bh(TIMER_BH);
}

#ifndef __alpha__

-- 
I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel.          Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature to help me spread!

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/