View Single Post
Old 11-09-02, 07:13 PM   #5
ScoobyDoo
Registered User
 
ScoobyDoo's Avatar
 
Join Date: Nov 2002
Posts: 11
Default

Hi again,

Thanks again for your thoughts, I do appreciate it.

=============================================

"either way, though, they're getting equal CPU"

But even this statement shows the futility of the driver implementation. The point is glxgears should not be consuming equal processor time! It should be consuming hardly any! When you run ps you dont expect every process listed to consume the same processor time as each other - you expect a handful of processes to be using *some*, with possibly a couple of processes really going for it (with good reason). The reason for this is that processes "sleep" when they dont need the CPU.

The glxgears process, when it is waiting for a vsync interrupt, does not need the CPU at all so it should sleep until the interrupt comes! When the scheduler offers glxgears some CPU time, instead of being greedy and grabbing as much as it can, it should say "no thank you, i dont need any right now".

Instead of doing this (like any nice Unix program should), it sits in a "busy-loop" which I can only imagine is something like:

while (1) {
if (vsync == true) break;
}

And this just hammers the CPU, grabbing as much time as it can get its greedy hands on.

It almost reminds me of the way people used to code for DOS in the old days when you didnt care about using up CPU time as no other programs would be running anyway. This is 2002! We use multitasking Operating Systems now!

As I have said, the Windows drivers do not seem to do this. They correctly sleep until the interrupt arrives.

=============================================

Here is some of the output from my box, running glxgears with vertical sync enabled (correctly runs at 60fps):

USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 150 93.7 2.2 76564 7212 p0 R+ 1:45AM 1:37.48 /usr/X11R6/bin/glxgears
root 97 0.0 0.3 1264 960 v0 Is 1:42AM 0:00.03 login -p root
root 98 0.0 0.2 1324 792 v0 I 1:42AM 0:00.03 -csh (csh)
root 101 0.0 0.4 1512 1244 v0 I 1:42AM 0:00.01 bash
root 102 0.0 0.1 636 444 v0 I+ 1:42AM 0:00.01 /bin/sh /usr/X11R6/bin/startx
root 112 0.0 0.3 1748 1108 v0 I+ 1:42AM 0:00.01 xinit /root/.xinitrc -- -nolisten tcp
root 118 0.0 1.0 4756 3268 v0 S 1:43AM 0:00.74 /usr/X11R6/bin/wmaker
root 119 0.0 0.9 3992 2984 v0 S 1:43AM 0:00.12 xterm

So, we can see that even with vertical syncing turned on, the CPU usage is > 90% (not quite my 100%, but close enough to grind a Unix multiuser system to a halt).

I added a small program that just spins in a loop. In a real life situation this could be an mp3 encoder, video player, or whatever. I reniced glxgears to -10 to give it priority.

The following shows how such a processor intensive task co-operates with an OpenGL application using Nvidia drivers under Linux or FreeBSD:

USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 150 71.8 2.2 76564 7212 p0 R<+ 1:45AM 5:02.06 /usr/X11R6/bin/glxgears
root 200 28.9 0.2 1256 732 p1 R+ 1:50AM 0:06.08 ./a.out
root 97 0.0 0.3 1264 960 v0 Is 1:42AM 0:00.03 login -p root
root 98 0.0 0.2 1324 792 v0 I 1:42AM 0:00.03 -csh (csh)
root 101 0.0 0.4 1512 1244 v0 I 1:42AM 0:00.01 bash
root 102 0.0 0.1 636 444 v0 I+ 1:42AM 0:00.01 /bin/sh /usr/X11R6/bin/startx
root 112 0.0 0.3 1748 1108 v0 I+ 1:42AM 0:00.01 xinit /root/.xinitrc -- -nolisten tcp
root 118 0.0 1.0 4756 3268 v0 S 1:43AM 0:01.13 /usr/X11R6/bin/wmaker
root 119 0.0 0.9 3992 2984 v0 S 1:43AM 0:00.14 xterm


So, here we see that a processor intensive task (a.out) can only grab about 30% of the CPU time. Also to note is that glxgears dropped down to about 40FPS. The way this should be is that the processor intensive task gets about > 90%, and glxgears gets < 10% (yet runs at full speed - it is hardly doing anything).

Again, why is it the worse scenario above, and not the better (like windows offers)?

The glxgears application should be "waiting" inside glxSwapBuffers() for most of its life doing *nothing* (as it would on Windows). Instead it spends most of its life inside glxSwapBuffers() hammering as much precious CPU time as it can get its greedy mits on, dragging the system to a halt with it.

If I hadnt have reniced glxgears, the FPS would have shot down to about 20-30FPS.

This situation is not good for multiuser/multitasking Operating Systems! It goes completely against some of the design philosophy of Unix.

This means that any time an OpenGL application needing video timing using the Nvidia drivers is run on a multiuser/multitasking system (Linux/FreeBSD) then no other processes have any hope of running concurrently at speed! Yet on Windows they will run fine!

=============================================

Can you see how this is a bad thing for any Unix-like OS?

The crux of the matter is I am trying to write an OpenGL desktop a bit like the what Apple have done with Aqua/Jaguar. You cannot have the GUI taking up 90% of the system resources leaving only 10% for all other applications!

I actually started to write my code on windows and was very happy with the vertical sync performance. The CPU usage was < 3% which is about what I would expect, especially pre optimisation. When I ported it to Linux the CPU usage was > 90% no matter how much I tried to optimise it.

Somebody help!!

Dont make me go and spend 3000 on a really slow macintosh and send FreeBSD/Linux to the dustbin!!

Jamie.

ps.

With regard to the poll, it does not return < 0 on my test program. It simply returns immediately, without waiting. I am not sure which events to look for, this was just a piece of code a guy said he used to use a year or so ago, but it stopped working when he updated his drivers/kernel one time.

Last edited by ScoobyDoo; 11-09-02 at 07:39 PM.
ScoobyDoo is offline