cpu consumption calculation - why these difference ?

Cedric ROUX (roux@ecoledoc.lip6.fr)
Tue, 18 May 1999 16:30:31 +0200


Hi kernel hackers.

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 ?)

Thank you by advance,
Sed.

------------------------------
- first program
------------------------------
/* first methode : blocking write. */

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/soundcard.h>
#include <math.h>

int open_audio(void)
{
int fd;
int play_precision=16;
int play_stereo=0;
int play_sample_rate=44100;
if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
if (errno == EBUSY) {
fprintf(stderr, "Audio device busy!\n");
return -1;
} else {
perror("Can't open /dev/dsp for writing");
return -1;
}
}
if(ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
fprintf(stderr, "config of samplesize failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
fprintf(stderr, "config of stereo failed");
close(fd);
return -1;
}
if (ioctl(fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
fprintf(stderr, "config of speed failed");
close(fd);
return -1;
}
return fd;
}

void use_cpu(short *buf)
{
static unsigned int j;
int i;

for (i=0; i<2048; i++) {
buf[i]=cos((float)j*2.*M_PI/(44100./440.))*30000.;
j++;
}
}

int main(void)
{
char buf[4096];
int fd=open_audio();

if (fd==-1)
return -1;

while(1) {
use_cpu((short *)buf);
if (write(fd, buf, 4096)==-1) {
perror("write");
close(fd);
return -1;
}
}

return 0;
}

------------------------------
- second program
------------------------------
/* second method : nonblocking write with a usleep (note that doing a blocking select won't change anything to the first method, so unblocking select must be used) */

#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/soundcard.h>
#include <math.h>

int open_audio(void)
{
int flags;
int fd;
int play_precision=16;
int play_stereo=0;
int play_sample_rate=44100;
if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
if (errno == EBUSY) {
fprintf(stderr, "Audio device busy!\n");
return -1;
} else {
perror("Can't open /dev/dsp for writing");
return -1;
}
}
/* let's unblock the sound */
if ((flags = fcntl(fd,F_GETFL,0)) == -1) {
fprintf(stderr, "fcntl F_GETFL on /dev/audio failed");
close(fd);
return -1;
}
flags |= O_NDELAY;
if (fcntl(fd, F_SETFL, flags) == -1) {
fprintf(stderr, "fcntl F_SETFL on /dev/audio failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
fprintf(stderr, "config of samplesize failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
fprintf(stderr, "config of stereo failed");
close(fd);
return -1;
}
if (ioctl(fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
fprintf(stderr, "config of speed failed");
close(fd);
return -1;
}
return fd;
}

void use_cpu(short *buf)
{
static unsigned int j;
int i;

for (i=0; i<2048; i++) {
buf[i]=cos((float)j*2.*M_PI/(44100./440.))*30000.;
j++;
}
}

int card_ready(int fd)
{
fd_set r, w, e;
struct timeval t;

FD_ZERO(&r);
FD_ZERO(&w);
FD_ZERO(&e);

t.tv_sec=0;
t.tv_usec=0;

FD_SET(fd, &w);

/* it's important not to block on the select, otherwise, cpu consumption is not changed */
if (select(FD_SETSIZE, &r, &w, &e, &t)==-1)
perror("select");
return FD_ISSET(fd, &w);
}

int main(void)
{
char buf[4096];
int fd=open_audio();

if (fd==-1)
return -1;

while(1) {
use_cpu((short *)buf);
/* wait for space available on the soundcard (as you see, we specifically usleep, we don't block on the select) */
while (!card_ready(fd))
usleep(10*1000);
if (write(fd, buf, 4096)==-1) {
perror("write");
close(fd);
return -1;
}
}

return 0;
}
---------------------------

-
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/